diff options
Diffstat (limited to 'OpenSim/Region')
22 files changed, 759 insertions, 435 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 05a2a63..630b6e6 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | |||
@@ -51,6 +51,44 @@ 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> |
@@ -282,12 +320,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
282 | private readonly IGroupsModule m_GroupsModule; | 320 | private readonly IGroupsModule m_GroupsModule; |
283 | 321 | ||
284 | private int m_cachedTextureSerial; | 322 | private int m_cachedTextureSerial; |
285 | private Timer m_avatarTerseUpdateTimer; | 323 | private PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_avatarTerseUpdates = |
286 | private List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_avatarTerseUpdates = new List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); | 324 | new PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); |
287 | private Timer m_primTerseUpdateTimer; | 325 | private PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_primTerseUpdates = |
288 | private List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_primTerseUpdates = new List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); | 326 | new PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); |
289 | private Timer m_primFullUpdateTimer; | 327 | private PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock> m_primFullUpdates = |
290 | private List<ObjectUpdatePacket.ObjectDataBlock> m_primFullUpdates = new List<ObjectUpdatePacket.ObjectDataBlock>(); | 328 | new PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock>(); |
291 | private int m_moneyBalance; | 329 | private int m_moneyBalance; |
292 | private int m_animationSequenceNumber = 1; | 330 | private int m_animationSequenceNumber = 1; |
293 | private bool m_SendLogoutPacketWhenClosing = true; | 331 | private bool m_SendLogoutPacketWhenClosing = true; |
@@ -312,9 +350,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
312 | // LL uses these limits, apparently. Compressed terse would be 23, but we don't have that yet | 350 | // LL uses these limits, apparently. Compressed terse would be 23, but we don't have that yet |
313 | protected int m_primTerseUpdatesPerPacket = 10; | 351 | protected int m_primTerseUpdatesPerPacket = 10; |
314 | protected int m_primFullUpdatesPerPacket = 14; | 352 | protected int m_primFullUpdatesPerPacket = 14; |
315 | protected int m_primTerseUpdateRate = 10; | ||
316 | protected int m_primFullUpdateRate = 14; | ||
317 | protected int m_avatarTerseUpdateRate = 50; | ||
318 | protected int m_avatarTerseUpdatesPerPacket = 5; | 353 | protected int m_avatarTerseUpdatesPerPacket = 5; |
319 | /// <summary>Number of texture packets to put on the queue each time the | 354 | /// <summary>Number of texture packets to put on the queue each time the |
320 | /// OnQueueEmpty event is triggered for the texture category</summary> | 355 | /// OnQueueEmpty event is triggered for the texture category</summary> |
@@ -438,25 +473,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
438 | // Remove ourselves from the scene | 473 | // Remove ourselves from the scene |
439 | m_scene.RemoveClient(AgentId); | 474 | m_scene.RemoveClient(AgentId); |
440 | 475 | ||
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 | 476 | // We can't reach into other scenes and close the connection |
453 | // We need to do this over grid communications | 477 | // We need to do this over grid communications |
454 | //m_scene.CloseAllAgents(CircuitCode); | 478 | //m_scene.CloseAllAgents(CircuitCode); |
455 | 479 | ||
456 | m_avatarTerseUpdateTimer.Dispose(); | ||
457 | m_primTerseUpdateTimer.Dispose(); | ||
458 | m_primFullUpdateTimer.Dispose(); | ||
459 | |||
460 | // Disable UDP handling for this client | 480 | // Disable UDP handling for this client |
461 | m_udpClient.Shutdown(); | 481 | m_udpClient.Shutdown(); |
462 | 482 | ||
@@ -483,18 +503,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
483 | 503 | ||
484 | public void Stop() | 504 | public void Stop() |
485 | { | 505 | { |
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 | 506 | ||
491 | if (m_primTerseUpdateTimer.Enabled) | ||
492 | lock (m_primTerseUpdateTimer) | ||
493 | m_primTerseUpdateTimer.Stop(); | ||
494 | |||
495 | if (m_primFullUpdateTimer.Enabled) | ||
496 | lock (m_primFullUpdateTimer) | ||
497 | m_primFullUpdateTimer.Stop(); | ||
498 | } | 507 | } |
499 | 508 | ||
500 | #endregion Client Methods | 509 | #endregion Client Methods |
@@ -590,18 +599,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
590 | 599 | ||
591 | public virtual void Start() | 600 | public virtual void Start() |
592 | { | 601 | { |
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); | 602 | m_scene.AddNewClient(this); |
606 | 603 | ||
607 | RefreshGroupMembership(); | 604 | RefreshGroupMembership(); |
@@ -3127,7 +3124,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3127 | 3124 | ||
3128 | avp.Sender.IsTrial = false; | 3125 | avp.Sender.IsTrial = false; |
3129 | avp.Sender.ID = agentID; | 3126 | avp.Sender.ID = agentID; |
3130 | OutPacket(avp, ThrottleOutPacketType.State); | 3127 | OutPacket(avp, ThrottleOutPacketType.Task); |
3131 | } | 3128 | } |
3132 | 3129 | ||
3133 | public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs) | 3130 | public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs) |
@@ -3159,33 +3156,221 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3159 | 3156 | ||
3160 | #endregion | 3157 | #endregion |
3161 | 3158 | ||
3159 | #region Prim/Avatar Updates | ||
3160 | |||
3161 | /*void SendObjectUpdate(SceneObjectPart obj, PrimFlags creatorFlags, PrimUpdateFlags updateFlags) | ||
3162 | { | ||
3163 | bool canUseCompressed, canUseImproved; | ||
3164 | UpdateFlagsToPacketType(creatorFlags, updateFlags, out canUseCompressed, out canUseImproved); | ||
3165 | |||
3166 | if (!canUseImproved && !canUseCompressed) | ||
3167 | SendFullObjectUpdate(obj, creatorFlags, updateFlags); | ||
3168 | else if (!canUseImproved) | ||
3169 | SendObjectUpdateCompressed(obj, creatorFlags, updateFlags); | ||
3170 | else | ||
3171 | SendImprovedTerseObjectUpdate(obj, creatorFlags, updateFlags); | ||
3172 | } | ||
3173 | |||
3174 | void SendFullObjectUpdate(SceneObjectPart obj, PrimFlags creatorFlags, PrimUpdateFlags updateFlags) | ||
3175 | { | ||
3176 | IClientAPI owner; | ||
3177 | if (m_scene.ClientManager.TryGetValue(obj.OwnerID, out owner) && owner is LLClientView) | ||
3178 | { | ||
3179 | LLClientView llOwner = (LLClientView)owner; | ||
3180 | |||
3181 | // Send an update out to the owner | ||
3182 | ObjectUpdatePacket updateToOwner = new ObjectUpdatePacket(); | ||
3183 | updateToOwner.RegionData.RegionHandle = obj.RegionHandle; | ||
3184 | //updateToOwner.RegionData.TimeDilation = (ushort)(timeDilation * (float)UInt16.MaxValue); | ||
3185 | updateToOwner.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; | ||
3186 | updateToOwner.ObjectData[0] = BuildUpdateBlock(obj, obj.Flags | creatorFlags | PrimFlags.ObjectYouOwner, 0); | ||
3187 | |||
3188 | m_udpServer.SendPacket(llOwner.UDPClient, updateToOwner, ThrottleOutPacketType.State, true); | ||
3189 | } | ||
3190 | |||
3191 | // Send an update out to everyone else | ||
3192 | ObjectUpdatePacket updateToOthers = new ObjectUpdatePacket(); | ||
3193 | updateToOthers.RegionData.RegionHandle = obj.RegionHandle; | ||
3194 | //updateToOthers.RegionData.TimeDilation = (ushort)(timeDilation * (float)UInt16.MaxValue); | ||
3195 | updateToOthers.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; | ||
3196 | updateToOthers.ObjectData[0] = BuildUpdateBlock(obj, obj.Flags, 0); | ||
3197 | |||
3198 | m_scene.ClientManager.ForEach( | ||
3199 | delegate(IClientAPI client) | ||
3200 | { | ||
3201 | if (client.AgentId != obj.OwnerID && client is LLClientView) | ||
3202 | { | ||
3203 | LLClientView llClient = (LLClientView)client; | ||
3204 | m_udpServer.SendPacket(llClient.UDPClient, updateToOthers, ThrottleOutPacketType.State, true); | ||
3205 | } | ||
3206 | } | ||
3207 | ); | ||
3208 | } | ||
3209 | |||
3210 | void SendObjectUpdateCompressed(SceneObjectPart obj, PrimFlags creatorFlags, PrimUpdateFlags updateFlags) | ||
3211 | { | ||
3212 | } | ||
3213 | |||
3214 | void SendImprovedTerseObjectUpdate(SceneObjectPart obj, PrimFlags creatorFlags, PrimUpdateFlags updateFlags) | ||
3215 | { | ||
3216 | } | ||
3217 | |||
3218 | void UpdateFlagsToPacketType(PrimFlags creatorFlags, PrimUpdateFlags updateFlags, out bool canUseCompressed, out bool canUseImproved) | ||
3219 | { | ||
3220 | canUseCompressed = true; | ||
3221 | canUseImproved = true; | ||
3222 | |||
3223 | if ((updateFlags & PrimUpdateFlags.FullUpdate) == PrimUpdateFlags.FullUpdate || creatorFlags != PrimFlags.None) | ||
3224 | { | ||
3225 | canUseCompressed = false; | ||
3226 | canUseImproved = false; | ||
3227 | } | ||
3228 | else | ||
3229 | { | ||
3230 | if ((updateFlags & PrimUpdateFlags.Velocity) != 0 || | ||
3231 | (updateFlags & PrimUpdateFlags.Acceleration) != 0 || | ||
3232 | (updateFlags & PrimUpdateFlags.CollisionPlane) != 0 || | ||
3233 | (updateFlags & PrimUpdateFlags.Joint) != 0) | ||
3234 | { | ||
3235 | canUseCompressed = false; | ||
3236 | } | ||
3237 | |||
3238 | if ((updateFlags & PrimUpdateFlags.PrimFlags) != 0 || | ||
3239 | (updateFlags & PrimUpdateFlags.ParentID) != 0 || | ||
3240 | (updateFlags & PrimUpdateFlags.Scale) != 0 || | ||
3241 | (updateFlags & PrimUpdateFlags.PrimData) != 0 || | ||
3242 | (updateFlags & PrimUpdateFlags.Text) != 0 || | ||
3243 | (updateFlags & PrimUpdateFlags.NameValue) != 0 || | ||
3244 | (updateFlags & PrimUpdateFlags.ExtraData) != 0 || | ||
3245 | (updateFlags & PrimUpdateFlags.TextureAnim) != 0 || | ||
3246 | (updateFlags & PrimUpdateFlags.Sound) != 0 || | ||
3247 | (updateFlags & PrimUpdateFlags.Particles) != 0 || | ||
3248 | (updateFlags & PrimUpdateFlags.Material) != 0 || | ||
3249 | (updateFlags & PrimUpdateFlags.ClickAction) != 0 || | ||
3250 | (updateFlags & PrimUpdateFlags.MediaURL) != 0 || | ||
3251 | (updateFlags & PrimUpdateFlags.Joint) != 0) | ||
3252 | { | ||
3253 | canUseImproved = false; | ||
3254 | } | ||
3255 | } | ||
3256 | } | ||
3257 | |||
3258 | static ObjectUpdatePacket.ObjectDataBlock BuildUpdateBlockFromPrim(SceneObjectPart prim, UUID assetID, PrimFlags flags, uint crc) | ||
3259 | { | ||
3260 | byte[] objectData = new byte[60]; | ||
3261 | prim.OffsetPosition.ToBytes(objectData, 0); | ||
3262 | prim.Velocity.ToBytes(objectData, 12); | ||
3263 | prim.Acceleration.ToBytes(objectData, 24); | ||
3264 | prim.RotationOffset.ToBytes(objectData, 36); | ||
3265 | prim.AngularVelocity.ToBytes(objectData, 48); | ||
3266 | |||
3267 | ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); | ||
3268 | update.ClickAction = (byte)prim.ClickAction; | ||
3269 | update.CRC = crc; | ||
3270 | update.ExtraParams = prim.Shape.ExtraParams ?? Utils.EmptyBytes; | ||
3271 | update.Flags = (byte)flags; | ||
3272 | update.FullID = prim.UUID; | ||
3273 | update.ID = prim.LocalId; | ||
3274 | //update.JointAxisOrAnchor = Vector3.Zero; // These are deprecated | ||
3275 | //update.JointPivot = Vector3.Zero; | ||
3276 | //update.JointType = 0; | ||
3277 | update.Material = prim.Material; | ||
3278 | update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim | ||
3279 | if (prim.IsAttachment) | ||
3280 | update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + assetID); | ||
3281 | else | ||
3282 | update.NameValue = Utils.EmptyBytes; | ||
3283 | update.ObjectData = objectData; | ||
3284 | update.ParentID = prim.ParentID; | ||
3285 | update.PathBegin = prim.Shape.PathBegin; | ||
3286 | update.PathCurve = prim.Shape.PathCurve; | ||
3287 | update.PathEnd = prim.Shape.PathEnd; | ||
3288 | update.PathRadiusOffset = prim.Shape.PathRadiusOffset; | ||
3289 | update.PathRevolutions = prim.Shape.PathRevolutions; | ||
3290 | update.PathScaleX = prim.Shape.PathScaleX; | ||
3291 | update.PathScaleY = prim.Shape.PathScaleY; | ||
3292 | update.PathShearX = prim.Shape.PathShearX; | ||
3293 | update.PathShearY = prim.Shape.PathShearY; | ||
3294 | update.PathSkew = prim.Shape.PathSkew; | ||
3295 | update.PathTaperX = prim.Shape.PathTaperX; | ||
3296 | update.PathTaperY = prim.Shape.PathTaperY; | ||
3297 | update.PathTwist = prim.Shape.PathTwist; | ||
3298 | update.PathTwistBegin = prim.Shape.PathTwistBegin; | ||
3299 | update.PCode = prim.Shape.PCode; | ||
3300 | update.ProfileBegin = prim.Shape.ProfileBegin; | ||
3301 | update.ProfileCurve = prim.Shape.ProfileCurve; | ||
3302 | update.ProfileEnd = prim.Shape.ProfileEnd; | ||
3303 | update.ProfileHollow = prim.Shape.ProfileHollow; | ||
3304 | update.PSBlock = prim.ParticleSystem ?? Utils.EmptyBytes; | ||
3305 | update.TextColor = new Color4(prim.Color).GetBytes(true); | ||
3306 | update.TextureAnim = prim.TextureAnimation ?? Utils.EmptyBytes; | ||
3307 | update.TextureEntry = prim.Shape.TextureEntry ?? Utils.EmptyBytes; | ||
3308 | update.Scale = prim.Scale; | ||
3309 | update.State = prim.Shape.State; | ||
3310 | update.Text = Util.StringToBytes256(prim.Text); | ||
3311 | update.UpdateFlags = (uint)flags; | ||
3312 | |||
3313 | if (prim.Sound != UUID.Zero) | ||
3314 | { | ||
3315 | update.Sound = prim.Sound; | ||
3316 | update.OwnerID = prim.OwnerID; | ||
3317 | update.Gain = (float)prim.SoundGain; | ||
3318 | update.Radius = (float)prim.SoundRadius; | ||
3319 | } | ||
3320 | |||
3321 | switch ((PCode)prim.Shape.PCode) | ||
3322 | { | ||
3323 | case PCode.Grass: | ||
3324 | case PCode.Tree: | ||
3325 | case PCode.NewTree: | ||
3326 | update.Data = new byte[] { prim.Shape.State }; | ||
3327 | break; | ||
3328 | default: | ||
3329 | // TODO: Support ScratchPad | ||
3330 | //if (prim.ScratchPad != null) | ||
3331 | //{ | ||
3332 | // update.Data = new byte[prim.ScratchPad.Length]; | ||
3333 | // Buffer.BlockCopy(prim.ScratchPad, 0, update.Data, 0, update.Data.Length); | ||
3334 | //} | ||
3335 | //else | ||
3336 | //{ | ||
3337 | // update.Data = Utils.EmptyBytes; | ||
3338 | //} | ||
3339 | update.Data = Utils.EmptyBytes; | ||
3340 | break; | ||
3341 | } | ||
3342 | |||
3343 | return update; | ||
3344 | }*/ | ||
3345 | |||
3346 | #endregion Prim/Avatar Updates | ||
3347 | |||
3162 | #region Avatar Packet/data sending Methods | 3348 | #region Avatar Packet/data sending Methods |
3163 | 3349 | ||
3164 | /// <summary> | 3350 | /// <summary> |
3165 | /// send a objectupdate packet with information about the clients avatar | 3351 | /// send a objectupdate packet with information about the clients avatar |
3166 | /// </summary> | 3352 | /// </summary> |
3167 | public void SendAvatarData(ulong regionHandle, string firstName, string lastName, string grouptitle, UUID avatarID, | 3353 | public void SendAvatarData(SendAvatarData data) |
3168 | uint avatarLocalID, Vector3 Pos, byte[] textureEntry, uint parentID, Quaternion rotation) | ||
3169 | { | 3354 | { |
3170 | ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); | 3355 | ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); |
3171 | // TODO: don't create new blocks if recycling an old packet | 3356 | // TODO: don't create new blocks if recycling an old packet |
3172 | objupdate.RegionData.RegionHandle = regionHandle; | 3357 | objupdate.RegionData.RegionHandle = data.regionHandle; |
3173 | objupdate.RegionData.TimeDilation = ushort.MaxValue; | 3358 | objupdate.RegionData.TimeDilation = ushort.MaxValue; |
3174 | objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; | 3359 | objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; |
3175 | objupdate.ObjectData[0] = CreateDefaultAvatarPacket(textureEntry); | 3360 | objupdate.ObjectData[0] = CreateDefaultAvatarPacket(data.textureEntry); |
3176 | 3361 | ||
3177 | //give this avatar object a local id and assign the user a name | 3362 | //give this avatar object a local id and assign the user a name |
3178 | objupdate.ObjectData[0].ID = avatarLocalID; | 3363 | objupdate.ObjectData[0].ID = data.avatarLocalID; |
3179 | objupdate.ObjectData[0].FullID = avatarID; | 3364 | objupdate.ObjectData[0].FullID = data.avatarID; |
3180 | objupdate.ObjectData[0].ParentID = parentID; | 3365 | objupdate.ObjectData[0].ParentID = data.parentID; |
3181 | objupdate.ObjectData[0].NameValue = | 3366 | objupdate.ObjectData[0].NameValue = |
3182 | Utils.StringToBytes("FirstName STRING RW SV " + firstName + "\nLastName STRING RW SV " + lastName + "\nTitle STRING RW SV " + grouptitle); | 3367 | Utils.StringToBytes("FirstName STRING RW SV " + data.firstName + "\nLastName STRING RW SV " + data.lastName + "\nTitle STRING RW SV " + data.grouptitle); |
3183 | 3368 | ||
3184 | Vector3 pos2 = new Vector3(Pos.X, Pos.Y, Pos.Z); | 3369 | Vector3 pos2 = new Vector3(data.Pos.X, data.Pos.Y, data.Pos.Z); |
3185 | byte[] pb = pos2.GetBytes(); | 3370 | byte[] pb = pos2.GetBytes(); |
3186 | Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length); | 3371 | Array.Copy(pb, 0, objupdate.ObjectData[0].ObjectData, 16, pb.Length); |
3187 | 3372 | ||
3188 | byte[] rot = rotation.GetBytes(); | 3373 | byte[] rot = data.rotation.GetBytes(); |
3189 | Array.Copy(rot, 0, objupdate.ObjectData[0].ObjectData, 52, rot.Length); | 3374 | Array.Copy(rot, 0, objupdate.ObjectData[0].ObjectData, 52, rot.Length); |
3190 | 3375 | ||
3191 | objupdate.Header.Zerocoded = true; | 3376 | objupdate.Header.Zerocoded = true; |
@@ -3196,38 +3381,31 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3196 | /// Send a terse positional/rotation/velocity update about an avatar | 3381 | /// Send a terse positional/rotation/velocity update about an avatar |
3197 | /// to the client. This avatar can be that of the client itself. | 3382 | /// to the client. This avatar can be that of the client itself. |
3198 | /// </summary> | 3383 | /// </summary> |
3199 | public virtual void SendAvatarTerseUpdate(ulong regionHandle, | 3384 | public virtual void SendAvatarTerseUpdate(SendAvatarTerseData data) |
3200 | ushort timeDilation, uint localID, Vector3 position, | ||
3201 | Vector3 velocity, Quaternion rotation, UUID agentid) | ||
3202 | { | 3385 | { |
3386 | if (data.priority == double.NaN) | ||
3387 | { | ||
3388 | m_log.Error("[LLClientView] SendAvatarTerseUpdate received a NaN priority, dropping update"); | ||
3389 | return; | ||
3390 | } | ||
3391 | |||
3392 | Quaternion rotation = data.rotation; | ||
3393 | |||
3203 | if (rotation.X == rotation.Y && | 3394 | if (rotation.X == rotation.Y && |
3204 | rotation.Y == rotation.Z && | 3395 | rotation.Y == rotation.Z && |
3205 | rotation.Z == rotation.W && rotation.W == 0) | 3396 | rotation.Z == rotation.W && rotation.W == 0) |
3206 | rotation = Quaternion.Identity; | 3397 | rotation = Quaternion.Identity; |
3207 | 3398 | ||
3208 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = | 3399 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = |
3209 | CreateAvatarImprovedBlock(localID, position, velocity,rotation); | 3400 | CreateAvatarImprovedBlock(data.localID, data.position, data.velocity, rotation); |
3210 | 3401 | ||
3211 | lock (m_avatarTerseUpdates) | 3402 | lock (m_avatarTerseUpdates.SyncRoot) |
3212 | { | 3403 | m_avatarTerseUpdates.Enqueue(data.priority, terseBlock, data.localID); |
3213 | m_avatarTerseUpdates.Add(terseBlock); | ||
3214 | |||
3215 | // If packet is full or own movement packet, send it. | ||
3216 | if (m_avatarTerseUpdates.Count >= m_avatarTerseUpdatesPerPacket) | ||
3217 | { | ||
3218 | ProcessAvatarTerseUpdates(this, null); | ||
3219 | } | ||
3220 | else if (m_avatarTerseUpdates.Count == 1) | ||
3221 | { | ||
3222 | lock (m_avatarTerseUpdateTimer) | ||
3223 | m_avatarTerseUpdateTimer.Start(); | ||
3224 | } | ||
3225 | } | ||
3226 | } | 3404 | } |
3227 | 3405 | ||
3228 | private void ProcessAvatarTerseUpdates(object sender, ElapsedEventArgs e) | 3406 | private void ProcessAvatarTerseUpdates() |
3229 | { | 3407 | { |
3230 | lock (m_avatarTerseUpdates) | 3408 | lock (m_avatarTerseUpdates.SyncRoot) |
3231 | { | 3409 | { |
3232 | ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); | 3410 | ImprovedTerseObjectUpdatePacket terse = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); |
3233 | 3411 | ||
@@ -3247,34 +3425,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3247 | byte[] zerobuffer = new byte[1024]; | 3425 | byte[] zerobuffer = new byte[1024]; |
3248 | byte[] blockbuffer = new byte[1024]; | 3426 | byte[] blockbuffer = new byte[1024]; |
3249 | 3427 | ||
3428 | Queue<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> updates = new Queue<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); | ||
3429 | |||
3250 | for (count = 0 ; count < max ; count++) | 3430 | for (count = 0 ; count < max ; count++) |
3251 | { | 3431 | { |
3252 | int length = 0; | 3432 | int length = 0; |
3253 | m_avatarTerseUpdates[count].ToBytes(blockbuffer, ref length); | 3433 | m_avatarTerseUpdates.Peek().ToBytes(blockbuffer, ref length); |
3254 | length = Helpers.ZeroEncode(blockbuffer, length, zerobuffer); | 3434 | length = Helpers.ZeroEncode(blockbuffer, length, zerobuffer); |
3255 | if (size + length > Packet.MTU) | 3435 | if (size + length > Packet.MTU) |
3256 | break; | 3436 | break; |
3257 | size += length; | 3437 | size += length; |
3438 | updates.Enqueue(m_avatarTerseUpdates.Dequeue()); | ||
3258 | } | 3439 | } |
3259 | 3440 | ||
3260 | terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count]; | 3441 | terse.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[count]; |
3261 | 3442 | ||
3262 | for (int i = 0 ; i < count ; i++) | 3443 | for (int i = 0 ; i < count ; i++) |
3263 | { | 3444 | terse.ObjectData[i] = updates.Dequeue(); |
3264 | terse.ObjectData[i] = m_avatarTerseUpdates[0]; | ||
3265 | m_avatarTerseUpdates.RemoveAt(0); | ||
3266 | } | ||
3267 | 3445 | ||
3268 | terse.Header.Reliable = false; | 3446 | terse.Header.Reliable = false; |
3269 | terse.Header.Zerocoded = true; | 3447 | terse.Header.Zerocoded = true; |
3270 | // FIXME: Move this to ThrottleOutPacketType.State when the real prioritization code is committed | ||
3271 | OutPacket(terse, ThrottleOutPacketType.Task); | ||
3272 | 3448 | ||
3273 | if (m_avatarTerseUpdates.Count == 0) | 3449 | OutPacket(terse, ThrottleOutPacketType.State); |
3274 | { | ||
3275 | lock (m_avatarTerseUpdateTimer) | ||
3276 | m_avatarTerseUpdateTimer.Stop(); | ||
3277 | } | ||
3278 | } | 3450 | } |
3279 | } | 3451 | } |
3280 | 3452 | ||
@@ -3342,54 +3514,42 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3342 | OutPacket(attach, ThrottleOutPacketType.Task); | 3514 | OutPacket(attach, ThrottleOutPacketType.Task); |
3343 | } | 3515 | } |
3344 | 3516 | ||
3345 | public void SendPrimitiveToClient( | 3517 | public void SendPrimitiveToClient(SendPrimitiveData data) |
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 | { | 3518 | { |
3351 | byte[] textureanim = new byte[0]; | 3519 | if (data.priority == double.NaN) |
3352 | 3520 | { | |
3353 | SendPrimitiveToClient(regionHandle, timeDilation, localID, primShape, pos, vel, | 3521 | m_log.Error("[LLClientView] SendPrimitiveToClient received a NaN priority, dropping update"); |
3354 | acc, rotation, rvel, flags, | 3522 | return; |
3355 | objectID, ownerID, text, color, parentID, particleSystem, | 3523 | } |
3356 | clickAction, material, textureanim, false, 0, UUID.Zero, UUID.Zero, 0, 0, 0); | ||
3357 | } | ||
3358 | 3524 | ||
3359 | public void SendPrimitiveToClient( | 3525 | Quaternion rotation = data.rotation; |
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 | 3526 | ||
3367 | if (AttachPoint > 30 && ownerID != AgentId) // Someone else's HUD | 3527 | if (data.AttachPoint > 30 && data.ownerID != AgentId) // Someone else's HUD |
3368 | return; | 3528 | return; |
3369 | if (primShape.PCode == 9 && primShape.State != 0 && parentID == 0) | 3529 | if (data.primShape.PCode == 9 && data.primShape.State != 0 && data.parentID == 0) |
3370 | return; | 3530 | return; |
3371 | 3531 | ||
3372 | if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0) | 3532 | if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0.0f) |
3373 | rotation = Quaternion.Identity; | 3533 | rotation = Quaternion.Identity; |
3374 | 3534 | ||
3375 | ObjectUpdatePacket.ObjectDataBlock objectData = CreatePrimUpdateBlock(primShape, flags); | 3535 | ObjectUpdatePacket.ObjectDataBlock objectData = CreatePrimUpdateBlock(data.primShape, data.flags); |
3376 | 3536 | ||
3377 | objectData.ID = localID; | 3537 | objectData.ID = data.localID; |
3378 | objectData.FullID = objectID; | 3538 | objectData.FullID = data.objectID; |
3379 | objectData.OwnerID = ownerID; | 3539 | objectData.OwnerID = data.ownerID; |
3380 | 3540 | ||
3381 | objectData.Text = Util.StringToBytes256(text); | 3541 | objectData.Text = Util.StringToBytes256(data.text); |
3382 | objectData.TextColor[0] = color[0]; | 3542 | objectData.TextColor[0] = data.color[0]; |
3383 | objectData.TextColor[1] = color[1]; | 3543 | objectData.TextColor[1] = data.color[1]; |
3384 | objectData.TextColor[2] = color[2]; | 3544 | objectData.TextColor[2] = data.color[2]; |
3385 | objectData.TextColor[3] = color[3]; | 3545 | objectData.TextColor[3] = data.color[3]; |
3386 | objectData.ParentID = parentID; | 3546 | objectData.ParentID = data.parentID; |
3387 | objectData.PSBlock = particleSystem; | 3547 | objectData.PSBlock = data.particleSystem; |
3388 | objectData.ClickAction = clickAction; | 3548 | objectData.ClickAction = data.clickAction; |
3389 | objectData.Material = material; | 3549 | objectData.Material = data.material; |
3390 | objectData.Flags = 0; | 3550 | objectData.Flags = 0; |
3391 | 3551 | ||
3392 | if (attachment) | 3552 | if (data.attachment) |
3393 | { | 3553 | { |
3394 | // Necessary??? | 3554 | // Necessary??? |
3395 | objectData.JointAxisOrAnchor = new Vector3(0, 0, 2); | 3555 | objectData.JointAxisOrAnchor = new Vector3(0, 0, 2); |
@@ -3397,14 +3557,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3397 | 3557 | ||
3398 | // Item from inventory??? | 3558 | // Item from inventory??? |
3399 | objectData.NameValue = | 3559 | objectData.NameValue = |
3400 | Utils.StringToBytes("AttachItemID STRING RW SV " + AssetId.Guid); | 3560 | Utils.StringToBytes("AttachItemID STRING RW SV " + data.AssetId.Guid); |
3401 | objectData.State = (byte)((AttachPoint % 16) * 16 + (AttachPoint / 16)); | 3561 | objectData.State = (byte)((data.AttachPoint % 16) * 16 + (data.AttachPoint / 16)); |
3402 | } | 3562 | } |
3403 | 3563 | ||
3404 | // Xantor 20080528: Send sound info as well | 3564 | // Xantor 20080528: Send sound info as well |
3405 | // Xantor 20080530: Zero out everything if there's no SoundId, so zerocompression will work again | 3565 | // Xantor 20080530: Zero out everything if there's no SoundId, so zerocompression will work again |
3406 | objectData.Sound = SoundId; | 3566 | objectData.Sound = data.SoundId; |
3407 | if (SoundId == UUID.Zero) | 3567 | if (data.SoundId == UUID.Zero) |
3408 | { | 3568 | { |
3409 | objectData.OwnerID = UUID.Zero; | 3569 | objectData.OwnerID = UUID.Zero; |
3410 | objectData.Gain = 0.0f; | 3570 | objectData.Gain = 0.0f; |
@@ -3413,39 +3573,31 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3413 | } | 3573 | } |
3414 | else | 3574 | else |
3415 | { | 3575 | { |
3416 | objectData.OwnerID = ownerID; | 3576 | objectData.OwnerID = data.ownerID; |
3417 | objectData.Gain = (float)SoundGain; | 3577 | objectData.Gain = (float)data.SoundVolume; |
3418 | objectData.Radius = (float)SoundRadius; | 3578 | objectData.Radius = (float)data.SoundRadius; |
3419 | objectData.Flags = SoundFlags; | 3579 | objectData.Flags = data.SoundFlags; |
3420 | } | 3580 | } |
3421 | 3581 | ||
3422 | byte[] pb = pos.GetBytes(); | 3582 | byte[] pb = data.pos.GetBytes(); |
3423 | Array.Copy(pb, 0, objectData.ObjectData, 0, pb.Length); | 3583 | Buffer.BlockCopy(pb, 0, objectData.ObjectData, 0, pb.Length); |
3424 | 3584 | ||
3425 | byte[] vel = velocity.GetBytes(); | 3585 | byte[] vel = data.vel.GetBytes(); |
3426 | Array.Copy(vel, 0, objectData.ObjectData, pb.Length, vel.Length); | 3586 | Buffer.BlockCopy(vel, 0, objectData.ObjectData, pb.Length, vel.Length); |
3427 | 3587 | ||
3428 | byte[] rot = rotation.GetBytes(); | 3588 | byte[] rot = rotation.GetBytes(); |
3429 | Array.Copy(rot, 0, objectData.ObjectData, 36, rot.Length); | 3589 | Buffer.BlockCopy(rot, 0, objectData.ObjectData, 36, rot.Length); |
3430 | 3590 | ||
3431 | byte[] rvel = rotational_velocity.GetBytes(); | 3591 | byte[] rvel = data.rvel.GetBytes(); |
3432 | Array.Copy(rvel, 0, objectData.ObjectData, 36 + rot.Length, rvel.Length); | 3592 | Buffer.BlockCopy(rvel, 0, objectData.ObjectData, 36 + rot.Length, rvel.Length); |
3433 | 3593 | ||
3434 | if (textureanim.Length > 0) | 3594 | if (data.textureanim.Length > 0) |
3435 | { | 3595 | { |
3436 | objectData.TextureAnim = textureanim; | 3596 | objectData.TextureAnim = data.textureanim; |
3437 | } | 3597 | } |
3438 | 3598 | ||
3439 | lock (m_primFullUpdates) | 3599 | lock (m_primFullUpdates.SyncRoot) |
3440 | { | 3600 | m_primFullUpdates.Enqueue(data.priority, objectData, data.localID); |
3441 | if (m_primFullUpdates.Count == 0) | ||
3442 | m_primFullUpdateTimer.Start(); | ||
3443 | |||
3444 | m_primFullUpdates.Add(objectData); | ||
3445 | |||
3446 | if (m_primFullUpdates.Count >= m_primFullUpdatesPerPacket) | ||
3447 | ProcessPrimFullUpdates(this, null); | ||
3448 | } | ||
3449 | } | 3601 | } |
3450 | 3602 | ||
3451 | void HandleQueueEmpty(ThrottleOutPacketType queue) | 3603 | void HandleQueueEmpty(ThrottleOutPacketType queue) |
@@ -3455,6 +3607,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3455 | case ThrottleOutPacketType.Texture: | 3607 | case ThrottleOutPacketType.Texture: |
3456 | ProcessTextureRequests(); | 3608 | ProcessTextureRequests(); |
3457 | break; | 3609 | break; |
3610 | case ThrottleOutPacketType.State: | ||
3611 | int count = 0; | ||
3612 | |||
3613 | lock (m_avatarTerseUpdates.SyncRoot) | ||
3614 | count = m_avatarTerseUpdates.Count; | ||
3615 | if (count > 0) | ||
3616 | { | ||
3617 | ProcessAvatarTerseUpdates(); | ||
3618 | return; | ||
3619 | } | ||
3620 | |||
3621 | lock (m_primFullUpdates.SyncRoot) | ||
3622 | count = m_primFullUpdates.Count; | ||
3623 | if (count > 0) | ||
3624 | { | ||
3625 | ProcessPrimFullUpdates(); | ||
3626 | return; | ||
3627 | } | ||
3628 | |||
3629 | lock (m_primTerseUpdates.SyncRoot) | ||
3630 | count = m_primTerseUpdates.Count; | ||
3631 | if (count > 0) | ||
3632 | { | ||
3633 | ProcessPrimTerseUpdates(); | ||
3634 | return; | ||
3635 | } | ||
3636 | break; | ||
3458 | } | 3637 | } |
3459 | } | 3638 | } |
3460 | 3639 | ||
@@ -3464,18 +3643,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3464 | m_imageManager.ProcessImageQueue(m_textureSendLimit); | 3643 | m_imageManager.ProcessImageQueue(m_textureSendLimit); |
3465 | } | 3644 | } |
3466 | 3645 | ||
3467 | void ProcessPrimFullUpdates(object sender, ElapsedEventArgs e) | 3646 | void ProcessPrimFullUpdates() |
3468 | { | 3647 | { |
3469 | lock (m_primFullUpdates) | 3648 | lock (m_primFullUpdates.SyncRoot) |
3470 | { | 3649 | { |
3471 | if (m_primFullUpdates.Count == 0 && m_primFullUpdateTimer.Enabled) | ||
3472 | { | ||
3473 | lock (m_primFullUpdateTimer) | ||
3474 | m_primFullUpdateTimer.Stop(); | ||
3475 | |||
3476 | return; | ||
3477 | } | ||
3478 | |||
3479 | ObjectUpdatePacket outPacket = | 3650 | ObjectUpdatePacket outPacket = |
3480 | (ObjectUpdatePacket)PacketPool.Instance.GetPacket( | 3651 | (ObjectUpdatePacket)PacketPool.Instance.GetPacket( |
3481 | PacketType.ObjectUpdate); | 3652 | PacketType.ObjectUpdate); |
@@ -3495,74 +3666,63 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3495 | byte[] zerobuffer = new byte[1024]; | 3666 | byte[] zerobuffer = new byte[1024]; |
3496 | byte[] blockbuffer = new byte[1024]; | 3667 | byte[] blockbuffer = new byte[1024]; |
3497 | 3668 | ||
3669 | Queue<ObjectUpdatePacket.ObjectDataBlock> updates = new Queue<ObjectUpdatePacket.ObjectDataBlock>(); | ||
3670 | |||
3498 | for (count = 0 ; count < max ; count++) | 3671 | for (count = 0 ; count < max ; count++) |
3499 | { | 3672 | { |
3500 | int length = 0; | 3673 | int length = 0; |
3501 | m_primFullUpdates[count].ToBytes(blockbuffer, ref length); | 3674 | m_primFullUpdates.Peek().ToBytes(blockbuffer, ref length); |
3502 | length = Helpers.ZeroEncode(blockbuffer, length, zerobuffer); | 3675 | length = Helpers.ZeroEncode(blockbuffer, length, zerobuffer); |
3503 | if (size + length > Packet.MTU) | 3676 | if (size + length > Packet.MTU) |
3504 | break; | 3677 | break; |
3505 | size += length; | 3678 | size += length; |
3679 | updates.Enqueue(m_primFullUpdates.Dequeue()); | ||
3506 | } | 3680 | } |
3507 | 3681 | ||
3508 | outPacket.ObjectData = | 3682 | outPacket.ObjectData = |
3509 | new ObjectUpdatePacket.ObjectDataBlock[count]; | 3683 | new ObjectUpdatePacket.ObjectDataBlock[count]; |
3510 | 3684 | ||
3511 | for (int index = 0 ; index < count ; index++) | 3685 | for (int index = 0 ; index < count ; index++) |
3512 | { | 3686 | outPacket.ObjectData[index] = updates.Dequeue(); |
3513 | outPacket.ObjectData[index] = m_primFullUpdates[0]; | ||
3514 | m_primFullUpdates.RemoveAt(0); | ||
3515 | } | ||
3516 | 3687 | ||
3517 | outPacket.Header.Zerocoded = true; | 3688 | outPacket.Header.Zerocoded = true; |
3518 | OutPacket(outPacket, ThrottleOutPacketType.State); | 3689 | OutPacket(outPacket, ThrottleOutPacketType.State); |
3519 | |||
3520 | if (m_primFullUpdates.Count == 0 && m_primFullUpdateTimer.Enabled) | ||
3521 | lock (m_primFullUpdateTimer) | ||
3522 | m_primFullUpdateTimer.Stop(); | ||
3523 | } | 3690 | } |
3524 | } | 3691 | } |
3525 | 3692 | ||
3526 | /// <summary> | 3693 | /// <summary> |
3527 | /// | 3694 | /// |
3528 | /// </summary> | 3695 | /// </summary> |
3529 | public void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, | 3696 | //public void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, |
3530 | Quaternion rotation, Vector3 velocity, Vector3 rotationalvelocity, byte state, UUID AssetId, UUID ownerID, int attachPoint) | 3697 | // Quaternion rotation, Vector3 velocity, Vector3 rotationalvelocity, byte state, UUID AssetId, UUID ownerID, int attachPoint) |
3698 | public void SendPrimTerseUpdate(SendPrimitiveTerseData data) | ||
3531 | { | 3699 | { |
3532 | if (attachPoint > 30 && ownerID != AgentId) // Someone else's HUD | 3700 | if (data.priority == double.NaN) |
3701 | { | ||
3702 | m_log.Error("[LLClientView] SendPrimTerseUpdate received a NaN priority, dropping update"); | ||
3703 | return; | ||
3704 | } | ||
3705 | |||
3706 | Quaternion rotation = data.rotation; | ||
3707 | |||
3708 | if (data.attachPoint > 30 && data.owner != AgentId) // Someone else's HUD | ||
3533 | return; | 3709 | return; |
3534 | 3710 | ||
3535 | if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0) | 3711 | if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0) |
3536 | rotation = Quaternion.Identity; | 3712 | rotation = Quaternion.Identity; |
3537 | 3713 | ||
3538 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock objectData = | 3714 | ImprovedTerseObjectUpdatePacket.ObjectDataBlock objectData = |
3539 | CreatePrimImprovedBlock(localID, position, rotation, | 3715 | CreatePrimImprovedBlock(data.localID, data.position, rotation, |
3540 | velocity, rotationalvelocity, state); | 3716 | data.velocity, data.rotationalvelocity, data.state); |
3541 | 3717 | ||
3542 | lock (m_primTerseUpdates) | 3718 | lock (m_primTerseUpdates.SyncRoot) |
3543 | { | 3719 | m_primTerseUpdates.Enqueue(data.priority, objectData, data.localID); |
3544 | if (m_primTerseUpdates.Count == 0) | ||
3545 | m_primTerseUpdateTimer.Start(); | ||
3546 | |||
3547 | m_primTerseUpdates.Add(objectData); | ||
3548 | |||
3549 | if (m_primTerseUpdates.Count >= m_primTerseUpdatesPerPacket) | ||
3550 | ProcessPrimTerseUpdates(this, null); | ||
3551 | } | ||
3552 | } | 3720 | } |
3553 | 3721 | ||
3554 | void ProcessPrimTerseUpdates(object sender, ElapsedEventArgs e) | 3722 | void ProcessPrimTerseUpdates() |
3555 | { | 3723 | { |
3556 | lock (m_primTerseUpdates) | 3724 | lock (m_primTerseUpdates.SyncRoot) |
3557 | { | 3725 | { |
3558 | if (m_primTerseUpdates.Count == 0) | ||
3559 | { | ||
3560 | lock (m_primTerseUpdateTimer) | ||
3561 | m_primTerseUpdateTimer.Stop(); | ||
3562 | |||
3563 | return; | ||
3564 | } | ||
3565 | |||
3566 | ImprovedTerseObjectUpdatePacket outPacket = | 3726 | ImprovedTerseObjectUpdatePacket outPacket = |
3567 | (ImprovedTerseObjectUpdatePacket) | 3727 | (ImprovedTerseObjectUpdatePacket) |
3568 | PacketPool.Instance.GetPacket( | 3728 | PacketPool.Instance.GetPacket( |
@@ -3583,14 +3743,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3583 | byte[] zerobuffer = new byte[1024]; | 3743 | byte[] zerobuffer = new byte[1024]; |
3584 | byte[] blockbuffer = new byte[1024]; | 3744 | byte[] blockbuffer = new byte[1024]; |
3585 | 3745 | ||
3746 | Queue<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> updates = new Queue<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); | ||
3747 | |||
3586 | for (count = 0 ; count < max ; count++) | 3748 | for (count = 0 ; count < max ; count++) |
3587 | { | 3749 | { |
3588 | int length = 0; | 3750 | int length = 0; |
3589 | m_primTerseUpdates[count].ToBytes(blockbuffer, ref length); | 3751 | m_primTerseUpdates.Peek().ToBytes(blockbuffer, ref length); |
3590 | length = Helpers.ZeroEncode(blockbuffer, length, zerobuffer); | 3752 | length = Helpers.ZeroEncode(blockbuffer, length, zerobuffer); |
3591 | if (size + length > Packet.MTU) | 3753 | if (size + length > Packet.MTU) |
3592 | break; | 3754 | break; |
3593 | size += length; | 3755 | size += length; |
3756 | updates.Enqueue(m_primTerseUpdates.Dequeue()); | ||
3594 | } | 3757 | } |
3595 | 3758 | ||
3596 | outPacket.ObjectData = | 3759 | outPacket.ObjectData = |
@@ -3598,18 +3761,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3598 | ObjectDataBlock[count]; | 3761 | ObjectDataBlock[count]; |
3599 | 3762 | ||
3600 | for (int index = 0 ; index < count ; index++) | 3763 | for (int index = 0 ; index < count ; index++) |
3601 | { | 3764 | outPacket.ObjectData[index] = updates.Dequeue(); |
3602 | outPacket.ObjectData[index] = m_primTerseUpdates[0]; | ||
3603 | m_primTerseUpdates.RemoveAt(0); | ||
3604 | } | ||
3605 | 3765 | ||
3606 | outPacket.Header.Reliable = false; | 3766 | outPacket.Header.Reliable = false; |
3607 | outPacket.Header.Zerocoded = true; | 3767 | outPacket.Header.Zerocoded = true; |
3608 | OutPacket(outPacket, ThrottleOutPacketType.State); | 3768 | OutPacket(outPacket, ThrottleOutPacketType.State); |
3609 | |||
3610 | if (m_primTerseUpdates.Count == 0) | ||
3611 | lock (m_primTerseUpdateTimer) | ||
3612 | m_primTerseUpdateTimer.Stop(); | ||
3613 | } | 3769 | } |
3614 | } | 3770 | } |
3615 | 3771 | ||
@@ -3617,15 +3773,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3617 | { | 3773 | { |
3618 | while (m_primFullUpdates.Count > 0) | 3774 | while (m_primFullUpdates.Count > 0) |
3619 | { | 3775 | { |
3620 | ProcessPrimFullUpdates(this, null); | 3776 | ProcessPrimFullUpdates(); |
3621 | } | 3777 | } |
3622 | while (m_primTerseUpdates.Count > 0) | 3778 | while (m_primTerseUpdates.Count > 0) |
3623 | { | 3779 | { |
3624 | ProcessPrimTerseUpdates(this, null); | 3780 | ProcessPrimTerseUpdates(); |
3625 | } | 3781 | } |
3626 | while (m_avatarTerseUpdates.Count > 0) | 3782 | while (m_avatarTerseUpdates.Count > 0) |
3627 | { | 3783 | { |
3628 | ProcessAvatarTerseUpdates(this, null); | 3784 | ProcessAvatarTerseUpdates(); |
3629 | } | 3785 | } |
3630 | } | 3786 | } |
3631 | 3787 | ||
@@ -10371,5 +10527,136 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
10371 | pack.TextureData.TextureID = textureID; | 10527 | pack.TextureData.TextureID = textureID; |
10372 | OutPacket(pack, ThrottleOutPacketType.Task); | 10528 | OutPacket(pack, ThrottleOutPacketType.Task); |
10373 | } | 10529 | } |
10530 | |||
10531 | #region PriorityQueue | ||
10532 | private class PriorityQueue<TPriority, TValue> | ||
10533 | { | ||
10534 | private MinHeap<MinHeapItem>[] heaps = new MinHeap<MinHeapItem>[1]; | ||
10535 | private Dictionary<uint, LookupItem> lookup_table = new Dictionary<uint, LookupItem>(); | ||
10536 | private Comparison<TPriority> comparison; | ||
10537 | private object sync_root = new object(); | ||
10538 | |||
10539 | internal PriorityQueue() : | ||
10540 | this(MinHeap<MinHeapItem>.DEFAULT_CAPACITY, Comparer<TPriority>.Default) { } | ||
10541 | internal PriorityQueue(int capacity) : | ||
10542 | this(capacity, Comparer<TPriority>.Default) { } | ||
10543 | internal PriorityQueue(IComparer<TPriority> comparer) : | ||
10544 | this(new Comparison<TPriority>(comparer.Compare)) { } | ||
10545 | internal PriorityQueue(Comparison<TPriority> comparison) : | ||
10546 | this(MinHeap<MinHeapItem>.DEFAULT_CAPACITY, comparison) { } | ||
10547 | internal PriorityQueue(int capacity, IComparer<TPriority> comparer) : | ||
10548 | this(capacity, new Comparison<TPriority>(comparer.Compare)) { } | ||
10549 | internal PriorityQueue(int capacity, Comparison<TPriority> comparison) | ||
10550 | { | ||
10551 | for (int i = 0; i < heaps.Length; ++i) | ||
10552 | heaps[i] = new MinHeap<MinHeapItem>(capacity); | ||
10553 | this.comparison = comparison; | ||
10554 | } | ||
10555 | |||
10556 | internal object SyncRoot { get { return this.sync_root; } } | ||
10557 | internal int Count | ||
10558 | { | ||
10559 | get | ||
10560 | { | ||
10561 | int count = 0; | ||
10562 | for (int i = 0; i < heaps.Length; ++i) | ||
10563 | count = heaps[i].Count; | ||
10564 | return count; | ||
10565 | } | ||
10566 | } | ||
10567 | |||
10568 | internal bool Enqueue(TPriority priority, TValue value, uint local_id) | ||
10569 | { | ||
10570 | LookupItem item; | ||
10571 | |||
10572 | if (lookup_table.TryGetValue(local_id, out item)) | ||
10573 | { | ||
10574 | item.Heap[item.Handle] = new MinHeapItem(priority, value, local_id, this.comparison); | ||
10575 | return false; | ||
10576 | } | ||
10577 | else | ||
10578 | { | ||
10579 | item.Heap = heaps[0]; | ||
10580 | item.Heap.Add(new MinHeapItem(priority, value, local_id, this.comparison), ref item.Handle); | ||
10581 | lookup_table.Add(local_id, item); | ||
10582 | return true; | ||
10583 | } | ||
10584 | } | ||
10585 | |||
10586 | internal TValue Peek() | ||
10587 | { | ||
10588 | for (int i = 0; i < heaps.Length; ++i) | ||
10589 | if (heaps[i].Count > 0) | ||
10590 | return heaps[i].Min().Value; | ||
10591 | throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString())); | ||
10592 | } | ||
10593 | |||
10594 | internal TValue Dequeue() | ||
10595 | { | ||
10596 | for (int i = 0; i < heaps.Length; ++i) | ||
10597 | { | ||
10598 | if (heaps[i].Count > 0) | ||
10599 | { | ||
10600 | MinHeapItem item = heaps[i].RemoveMin(); | ||
10601 | lookup_table.Remove(item.LocalID); | ||
10602 | return item.Value; | ||
10603 | } | ||
10604 | } | ||
10605 | throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString())); | ||
10606 | } | ||
10607 | |||
10608 | #region MinHeapItem | ||
10609 | private struct MinHeapItem : IComparable<MinHeapItem> | ||
10610 | { | ||
10611 | private TPriority priority; | ||
10612 | private TValue value; | ||
10613 | private uint local_id; | ||
10614 | private Comparison<TPriority> comparison; | ||
10615 | |||
10616 | internal MinHeapItem(TPriority priority, TValue value, uint local_id) : | ||
10617 | this(priority, value, local_id, Comparer<TPriority>.Default) { } | ||
10618 | internal MinHeapItem(TPriority priority, TValue value, uint local_id, IComparer<TPriority> comparer) : | ||
10619 | this(priority, value, local_id, new Comparison<TPriority>(comparer.Compare)) { } | ||
10620 | internal MinHeapItem(TPriority priority, TValue value, uint local_id, Comparison<TPriority> comparison) | ||
10621 | { | ||
10622 | this.priority = priority; | ||
10623 | this.value = value; | ||
10624 | this.local_id = local_id; | ||
10625 | this.comparison = comparison; | ||
10626 | } | ||
10627 | |||
10628 | internal TPriority Priority { get { return this.priority; } } | ||
10629 | internal TValue Value { get { return this.value; } } | ||
10630 | internal uint LocalID { get { return this.local_id; } } | ||
10631 | |||
10632 | public override string ToString() | ||
10633 | { | ||
10634 | StringBuilder sb = new StringBuilder(); | ||
10635 | sb.Append("["); | ||
10636 | if (this.priority != null) | ||
10637 | sb.Append(this.priority.ToString()); | ||
10638 | sb.Append(","); | ||
10639 | if (this.value != null) | ||
10640 | sb.Append(this.value.ToString()); | ||
10641 | sb.Append("]"); | ||
10642 | return sb.ToString(); | ||
10643 | } | ||
10644 | |||
10645 | public int CompareTo(MinHeapItem other) | ||
10646 | { | ||
10647 | return this.comparison(this.priority, other.priority); | ||
10648 | } | ||
10649 | } | ||
10650 | #endregion | ||
10651 | |||
10652 | #region LookupItem | ||
10653 | private struct LookupItem { | ||
10654 | internal MinHeap<MinHeapItem> Heap; | ||
10655 | internal IHandle Handle; | ||
10656 | } | ||
10657 | #endregion | ||
10658 | } | ||
10659 | #endregion | ||
10660 | |||
10374 | } | 10661 | } |
10375 | } | 10662 | } |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs index 4eee6b6..8c42ca4 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs | |||
@@ -170,7 +170,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
170 | { | 170 | { |
171 | ThrottleOutPacketType type = (ThrottleOutPacketType)i; | 171 | ThrottleOutPacketType type = (ThrottleOutPacketType)i; |
172 | 172 | ||
173 | // Initialize the packet outboxes, where packets sit while they are waiting for tokens | ||
173 | m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>(); | 174 | m_packetOutboxes[i] = new OpenSim.Framework.LocklessQueue<OutgoingPacket>(); |
175 | // 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)); | 176 | m_throttleCategories[i] = new TokenBucket(m_throttle, rates.GetLimit(type), rates.GetRate(type)); |
175 | } | 177 | } |
176 | 178 | ||
@@ -293,36 +295,54 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
293 | int state = (int)((float)task * STATE_TASK_PERCENTAGE); | 295 | int state = (int)((float)task * STATE_TASK_PERCENTAGE); |
294 | task -= state; | 296 | task -= state; |
295 | 297 | ||
296 | int ceiling = Int32.MaxValue; | 298 | // Make sure none of the throttles are set below our packet MTU, |
297 | if (m_defaultThrottleRates.Total != 0) | 299 | // otherwise a throttle could become permanently clogged |
298 | { | 300 | resend = Math.Max(resend, Packet.MTU); |
299 | ceiling = m_defaultThrottleRates.Total; | 301 | land = Math.Max(land, Packet.MTU); |
300 | if (ceiling < Packet.MTU) ceiling = Packet.MTU; | 302 | wind = Math.Max(wind, Packet.MTU); |
301 | } | 303 | cloud = Math.Max(cloud, Packet.MTU); |
302 | 304 | task = Math.Max(task, Packet.MTU); | |
303 | resend = Utils.Clamp(resend, Packet.MTU, ceiling); | 305 | texture = Math.Max(texture, Packet.MTU); |
304 | land = Utils.Clamp(land, Packet.MTU, ceiling); | 306 | asset = Math.Max(asset, Packet.MTU); |
305 | wind = Utils.Clamp(wind, Packet.MTU, ceiling); | 307 | state = Math.Max(state, Packet.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 | 308 | ||
312 | int total = resend + land + wind + cloud + task + texture + asset + state; | 309 | int total = resend + land + wind + cloud + task + texture + asset + state; |
313 | int taskTotal = task + state; | ||
314 | 310 | ||
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}", | 311 | 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); | 312 | AgentID, resend, land, wind, cloud, task, texture, asset, state, total); |
317 | 313 | ||
318 | SetThrottle(ThrottleOutPacketType.Resend, resend, resend); | 314 | // Update the token buckets with new throttle values |
319 | SetThrottle(ThrottleOutPacketType.Land, land, land); | 315 | TokenBucket bucket; |
320 | SetThrottle(ThrottleOutPacketType.Wind, wind, wind); | 316 | |
321 | SetThrottle(ThrottleOutPacketType.Cloud, cloud, cloud); | 317 | bucket = m_throttle; |
322 | SetThrottle(ThrottleOutPacketType.Task, task, taskTotal); | 318 | bucket.MaxBurst = total; |
323 | SetThrottle(ThrottleOutPacketType.Texture, texture, texture); | 319 | |
324 | SetThrottle(ThrottleOutPacketType.Asset, asset, asset); | 320 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Resend]; |
325 | SetThrottle(ThrottleOutPacketType.State, state, taskTotal); | 321 | bucket.DripRate = bucket.MaxBurst = resend; |
322 | |||
323 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Land]; | ||
324 | bucket.DripRate = bucket.MaxBurst = land; | ||
325 | |||
326 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Wind]; | ||
327 | bucket.DripRate = bucket.MaxBurst = wind; | ||
328 | |||
329 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Cloud]; | ||
330 | bucket.DripRate = bucket.MaxBurst = cloud; | ||
331 | |||
332 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Asset]; | ||
333 | bucket.DripRate = bucket.MaxBurst = asset; | ||
334 | |||
335 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Task]; | ||
336 | bucket.DripRate = task + state + texture; | ||
337 | bucket.MaxBurst = task + state + texture; | ||
338 | |||
339 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.State]; | ||
340 | bucket.DripRate = state + texture; | ||
341 | bucket.MaxBurst = state + texture; | ||
342 | |||
343 | bucket = m_throttleCategories[(int)ThrottleOutPacketType.Texture]; | ||
344 | bucket.DripRate = texture; | ||
345 | bucket.MaxBurst = texture; | ||
326 | } | 346 | } |
327 | 347 | ||
328 | public byte[] GetThrottlesPacked() | 348 | public byte[] GetThrottlesPacked() |
@@ -342,17 +362,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
342 | return data; | 362 | return data; |
343 | } | 363 | } |
344 | 364 | ||
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) | 365 | public bool EnqueueOutgoing(OutgoingPacket packet) |
357 | { | 366 | { |
358 | int category = (int)packet.Category; | 367 | int category = (int)packet.Category; |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index 545a0bc..b11a80d 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | |||
@@ -285,7 +285,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
285 | // The packet grew larger than the bufferSize while zerocoding. | 285 | // The packet grew larger than the bufferSize while zerocoding. |
286 | // Remove the MSG_ZEROCODED flag and send the unencoded data | 286 | // Remove the MSG_ZEROCODED flag and send the unencoded data |
287 | // instead | 287 | // instead |
288 | m_log.Debug("[LLUDPSERVER]: Packet exceeded buffer size during zerocoding for " + type + ". Removing MSG_ZEROCODED flag"); | 288 | m_log.Debug("[LLUDPSERVER]: Packet exceeded buffer size during zerocoding for " + type + ". DataLength=" + dataLength + |
289 | " and BufferLength=" + buffer.Data.Length + ". Removing MSG_ZEROCODED flag"); | ||
289 | data[0] = (byte)(data[0] & ~Helpers.MSG_ZEROCODED); | 290 | data[0] = (byte)(data[0] & ~Helpers.MSG_ZEROCODED); |
290 | Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength); | 291 | Buffer.BlockCopy(data, 0, buffer.Data, 0, dataLength); |
291 | } | 292 | } |
@@ -513,7 +514,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
513 | IClientAPI client; | 514 | IClientAPI client; |
514 | if (!m_scene.ClientManager.TryGetValue(address, out client) || !(client is LLClientView)) | 515 | if (!m_scene.ClientManager.TryGetValue(address, out client) || !(client is LLClientView)) |
515 | { | 516 | { |
516 | m_log.Warn("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + | 517 | 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"); | 518 | " in " + m_scene.RegionInfo.RegionName + ", currently tracking " + m_scene.ClientManager.Count + " clients"); |
518 | return; | 519 | return; |
519 | } | 520 | } |
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..332d3ce 100644 --- a/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Land/LandManagementModule.cs | |||
@@ -1061,7 +1061,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1061 | { | 1061 | { |
1062 | land.LandData.OwnerID = ownerID; | 1062 | land.LandData.OwnerID = ownerID; |
1063 | 1063 | ||
1064 | m_scene.Broadcast(SendParcelOverlay); | 1064 | m_scene.ForEachClient(SendParcelOverlay); |
1065 | land.SendLandUpdateToClient(remote_client); | 1065 | land.SendLandUpdateToClient(remote_client); |
1066 | } | 1066 | } |
1067 | } | 1067 | } |
@@ -1083,7 +1083,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1083 | land.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; | 1083 | land.LandData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; |
1084 | else | 1084 | else |
1085 | land.LandData.OwnerID = m_scene.RegionInfo.MasterAvatarAssignedUUID; | 1085 | land.LandData.OwnerID = m_scene.RegionInfo.MasterAvatarAssignedUUID; |
1086 | m_scene.Broadcast(SendParcelOverlay); | 1086 | m_scene.ForEachClient(SendParcelOverlay); |
1087 | land.SendLandUpdateToClient(remote_client); | 1087 | land.SendLandUpdateToClient(remote_client); |
1088 | } | 1088 | } |
1089 | } | 1089 | } |
@@ -1107,7 +1107,7 @@ namespace OpenSim.Region.CoreModules.World.Land | |||
1107 | land.LandData.OwnerID = m_scene.RegionInfo.MasterAvatarAssignedUUID; | 1107 | land.LandData.OwnerID = m_scene.RegionInfo.MasterAvatarAssignedUUID; |
1108 | land.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); | 1108 | land.LandData.ClaimDate = Util.UnixTimeSinceEpoch(); |
1109 | land.LandData.IsGroupOwned = false; | 1109 | land.LandData.IsGroupOwned = false; |
1110 | m_scene.Broadcast(SendParcelOverlay); | 1110 | m_scene.ForEachClient(SendParcelOverlay); |
1111 | land.SendLandUpdateToClient(remote_client); | 1111 | land.SendLandUpdateToClient(remote_client); |
1112 | } | 1112 | } |
1113 | } | 1113 | } |
diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs index d651fd4..3799a02 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,11 @@ 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 | { | ||
540 | } | ||
541 | public virtual void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, | ||
542 | Vector3 position, Quaternion rotation, Vector3 velocity, | ||
543 | Vector3 rotationalvelocity, byte state, UUID AssetId, | ||
544 | UUID ownerID, int attachPoint) | ||
545 | { | 527 | { |
546 | } | 528 | } |
547 | 529 | ||
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/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 29d2a84..49c1ebf 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 | ||
@@ -269,9 +275,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
269 | private volatile bool shuttingdown = false; | 275 | private volatile bool shuttingdown = false; |
270 | 276 | ||
271 | private int m_lastUpdate = Environment.TickCount; | 277 | private int m_lastUpdate = Environment.TickCount; |
272 | private int m_maxPrimsPerFrame = 200; | ||
273 | private bool m_firstHeartbeat = true; | 278 | private bool m_firstHeartbeat = true; |
274 | 279 | ||
280 | private UpdatePrioritizationSchemes m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time; | ||
281 | |||
275 | private object m_deleting_scene_object = new object(); | 282 | private object m_deleting_scene_object = new object(); |
276 | 283 | ||
277 | // the minimum time that must elapse before a changed object will be considered for persisted | 284 | // the minimum time that must elapse before a changed object will be considered for persisted |
@@ -283,6 +290,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
283 | 290 | ||
284 | #region Properties | 291 | #region Properties |
285 | 292 | ||
293 | public UpdatePrioritizationSchemes UpdatePrioritizationScheme { get { return this.m_update_prioritization_scheme; } } | ||
294 | |||
286 | public AgentCircuitManager AuthenticateHandler | 295 | public AgentCircuitManager AuthenticateHandler |
287 | { | 296 | { |
288 | get { return m_authenticateHandler; } | 297 | get { return m_authenticateHandler; } |
@@ -327,12 +336,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
327 | get { return m_sceneGraph.m_syncRoot; } | 336 | get { return m_sceneGraph.m_syncRoot; } |
328 | } | 337 | } |
329 | 338 | ||
330 | public int MaxPrimsPerFrame | ||
331 | { | ||
332 | get { return m_maxPrimsPerFrame; } | ||
333 | set { m_maxPrimsPerFrame = value; } | ||
334 | } | ||
335 | |||
336 | /// <summary> | 339 | /// <summary> |
337 | /// This is for llGetRegionFPS | 340 | /// This is for llGetRegionFPS |
338 | /// </summary> | 341 | /// </summary> |
@@ -510,7 +513,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
510 | 513 | ||
511 | m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "DotNetEngine"); | 514 | m_defaultScriptEngine = startupConfig.GetString("DefaultScriptEngine", "DotNetEngine"); |
512 | 515 | ||
513 | m_maxPrimsPerFrame = startupConfig.GetInt("MaxPrimsPerFrame", 200); | ||
514 | IConfig packetConfig = m_config.Configs["PacketPool"]; | 516 | IConfig packetConfig = m_config.Configs["PacketPool"]; |
515 | if (packetConfig != null) | 517 | if (packetConfig != null) |
516 | { | 518 | { |
@@ -519,6 +521,30 @@ namespace OpenSim.Region.Framework.Scenes | |||
519 | } | 521 | } |
520 | 522 | ||
521 | m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl); | 523 | m_strictAccessControl = startupConfig.GetBoolean("StrictAccessControl", m_strictAccessControl); |
524 | |||
525 | IConfig interest_management_config = m_config.Configs["InterestManagement"]; | ||
526 | if (interest_management_config != null) | ||
527 | { | ||
528 | string update_prioritization_scheme = interest_management_config.GetString("UpdatePrioritizationScheme", "Time").Trim().ToLower(); | ||
529 | switch (update_prioritization_scheme) | ||
530 | { | ||
531 | case "time": | ||
532 | m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time; | ||
533 | break; | ||
534 | case "distance": | ||
535 | m_update_prioritization_scheme = UpdatePrioritizationSchemes.Distance; | ||
536 | break; | ||
537 | case "simpleangulardistance": | ||
538 | m_update_prioritization_scheme = UpdatePrioritizationSchemes.SimpleAngularDistance; | ||
539 | break; | ||
540 | default: | ||
541 | m_log.Warn("[SCENE]: UpdatePrioritizationScheme was not recognized, setting to default settomg of Time"); | ||
542 | m_update_prioritization_scheme = UpdatePrioritizationSchemes.Time; | ||
543 | break; | ||
544 | } | ||
545 | } | ||
546 | |||
547 | m_log.Info("[SCENE]: Using the " + m_update_prioritization_scheme + " prioritization scheme"); | ||
522 | } | 548 | } |
523 | catch | 549 | catch |
524 | { | 550 | { |
@@ -1200,15 +1226,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1200 | } | 1226 | } |
1201 | 1227 | ||
1202 | /// <summary> | 1228 | /// <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. | 1229 | /// Backup the scene. This acts as the main method of the backup thread. |
1213 | /// </summary> | 1230 | /// </summary> |
1214 | /// <returns></returns> | 1231 | /// <returns></returns> |
@@ -3054,17 +3071,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
3054 | } | 3071 | } |
3055 | 3072 | ||
3056 | m_eventManager.TriggerOnRemovePresence(agentID); | 3073 | m_eventManager.TriggerOnRemovePresence(agentID); |
3057 | Broadcast(delegate(IClientAPI client) | 3074 | ForEachClient( |
3058 | { | 3075 | delegate(IClientAPI client) |
3059 | try | 3076 | { |
3060 | { | 3077 | //We can safely ignore null reference exceptions. It means the avatar is dead and cleaned up anyway |
3061 | client.SendKillObject(avatar.RegionHandle, avatar.LocalId); | 3078 | try { client.SendKillObject(avatar.RegionHandle, avatar.LocalId); } |
3062 | } | 3079 | catch (NullReferenceException) { } |
3063 | catch (NullReferenceException) | 3080 | }); |
3064 | { | ||
3065 | //We can safely ignore null reference exceptions. It means the avatar are dead and cleaned up anyway. | ||
3066 | } | ||
3067 | }); | ||
3068 | 3081 | ||
3069 | ForEachScenePresence( | 3082 | ForEachScenePresence( |
3070 | delegate(ScenePresence presence) { presence.CoarseLocationChange(); }); | 3083 | delegate(ScenePresence presence) { presence.CoarseLocationChange(); }); |
@@ -3149,7 +3162,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3149 | return; | 3162 | return; |
3150 | } | 3163 | } |
3151 | } | 3164 | } |
3152 | Broadcast(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); }); | 3165 | ForEachClient(delegate(IClientAPI client) { client.SendKillObject(m_regionHandle, localID); }); |
3153 | } | 3166 | } |
3154 | 3167 | ||
3155 | #endregion | 3168 | #endregion |
@@ -4222,7 +4235,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4222 | 4235 | ||
4223 | public void ForEachClient(Action<IClientAPI> action) | 4236 | public void ForEachClient(Action<IClientAPI> action) |
4224 | { | 4237 | { |
4225 | m_sceneGraph.ForEachClient(action); | 4238 | ClientManager.ForEach(action); |
4226 | } | 4239 | } |
4227 | 4240 | ||
4228 | public void ForEachSOG(Action<SceneObjectGroup> action) | 4241 | public void ForEachSOG(Action<SceneObjectGroup> action) |
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs index 9cd2247..b9872ca 100644 --- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs +++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs | |||
@@ -613,7 +613,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
613 | 613 | ||
614 | newAvatar = new ScenePresence(client, m_parentScene, m_regInfo, appearance); | 614 | newAvatar = new ScenePresence(client, m_parentScene, m_regInfo, appearance); |
615 | newAvatar.IsChildAgent = true; | 615 | newAvatar.IsChildAgent = true; |
616 | newAvatar.MaxPrimsPerFrame = m_parentScene.MaxPrimsPerFrame; | ||
617 | 616 | ||
618 | AddScenePresence(newAvatar); | 617 | AddScenePresence(newAvatar); |
619 | 618 | ||
@@ -1107,23 +1106,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1107 | return UUID.Zero; | 1106 | return UUID.Zero; |
1108 | } | 1107 | } |
1109 | 1108 | ||
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) | 1109 | protected internal void ForEachSOG(Action<SceneObjectGroup> action) |
1128 | { | 1110 | { |
1129 | List<SceneObjectGroup> objlist = new List<SceneObjectGroup>(SceneObjectGroupsByFullID.Values); | 1111 | 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 d4cef7d..2153b9b 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -1817,7 +1817,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1817 | public void ServiceObjectPropertiesFamilyRequest(IClientAPI remoteClient, UUID AgentID, uint RequestFlags) | 1817 | public void ServiceObjectPropertiesFamilyRequest(IClientAPI remoteClient, UUID AgentID, uint RequestFlags) |
1818 | { | 1818 | { |
1819 | 1819 | ||
1820 | remoteClient.SendObjectPropertiesFamilyData(RequestFlags, RootPart.UUID, RootPart.ObjectOwner, RootPart.GroupID, RootPart.BaseMask, | 1820 | remoteClient.SendObjectPropertiesFamilyData(RequestFlags, RootPart.UUID, RootPart.OwnerID, RootPart.GroupID, RootPart.BaseMask, |
1821 | RootPart.OwnerMask, RootPart.GroupMask, RootPart.EveryoneMask, RootPart.NextOwnerMask, | 1821 | RootPart.OwnerMask, RootPart.GroupMask, RootPart.EveryoneMask, RootPart.NextOwnerMask, |
1822 | RootPart.OwnershipCost, RootPart.ObjectSaleType, RootPart.SalePrice, RootPart.Category, | 1822 | RootPart.OwnershipCost, RootPart.ObjectSaleType, RootPart.SalePrice, RootPart.Category, |
1823 | RootPart.CreatorID, RootPart.Name, RootPart.Description); | 1823 | RootPart.CreatorID, RootPart.Name, RootPart.Description); |
@@ -3343,5 +3343,77 @@ namespace OpenSim.Region.Framework.Scenes | |||
3343 | 3343 | ||
3344 | return true; | 3344 | return true; |
3345 | } | 3345 | } |
3346 | |||
3347 | public double GetUpdatePriority(IClientAPI client) | ||
3348 | { | ||
3349 | switch (Scene.UpdatePrioritizationScheme) | ||
3350 | { | ||
3351 | case Scene.UpdatePrioritizationSchemes.Time: | ||
3352 | return GetPriorityByTime(); | ||
3353 | case Scene.UpdatePrioritizationSchemes.Distance: | ||
3354 | return GetPriorityByDistance(client); | ||
3355 | case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance: | ||
3356 | return GetPriorityBySimpleAngularDistance(client); | ||
3357 | default: | ||
3358 | throw new InvalidOperationException("UpdatePrioritizationScheme not defined"); | ||
3359 | } | ||
3360 | } | ||
3361 | |||
3362 | private double GetPriorityByTime() | ||
3363 | { | ||
3364 | return DateTime.Now.ToOADate(); | ||
3365 | } | ||
3366 | |||
3367 | private double GetPriorityByDistance(IClientAPI client) | ||
3368 | { | ||
3369 | ScenePresence presence = Scene.GetScenePresence(client.AgentId); | ||
3370 | if (presence != null) | ||
3371 | { | ||
3372 | return GetPriorityByDistance((presence.IsChildAgent) ? | ||
3373 | presence.AbsolutePosition : presence.CameraPosition); | ||
3374 | } | ||
3375 | return double.NaN; | ||
3376 | } | ||
3377 | |||
3378 | private double GetPriorityBySimpleAngularDistance(IClientAPI client) | ||
3379 | { | ||
3380 | ScenePresence presence = Scene.GetScenePresence(client.AgentId); | ||
3381 | if (presence != null) | ||
3382 | { | ||
3383 | return GetPriorityBySimpleAngularDistance((presence.IsChildAgent) ? | ||
3384 | presence.AbsolutePosition : presence.CameraPosition); | ||
3385 | } | ||
3386 | return double.NaN; | ||
3387 | } | ||
3388 | |||
3389 | public double GetPriorityByDistance(Vector3 position) | ||
3390 | { | ||
3391 | return Vector3.Distance(AbsolutePosition, position); | ||
3392 | } | ||
3393 | |||
3394 | public double GetPriorityBySimpleAngularDistance(Vector3 position) | ||
3395 | { | ||
3396 | double distance = Vector3.Distance(position, AbsolutePosition); | ||
3397 | if (distance >= double.Epsilon) | ||
3398 | { | ||
3399 | float height; | ||
3400 | Vector3 box = GetAxisAlignedBoundingBox(out height); | ||
3401 | |||
3402 | double angle = box.X / distance; | ||
3403 | double max = angle; | ||
3404 | |||
3405 | angle = box.Y / distance; | ||
3406 | if (max < angle) | ||
3407 | max = angle; | ||
3408 | |||
3409 | angle = box.Z / distance; | ||
3410 | if (max < angle) | ||
3411 | max = angle; | ||
3412 | |||
3413 | return -max; | ||
3414 | } | ||
3415 | else | ||
3416 | return double.MinValue; | ||
3417 | } | ||
3346 | } | 3418 | } |
3347 | } | 3419 | } |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index 801a7db..79f6366 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -853,16 +853,6 @@ if (m_shape != null) { | |||
853 | return m_offsetPosition + m_groupPosition; } | 853 | return m_offsetPosition + m_groupPosition; } |
854 | } | 854 | } |
855 | 855 | ||
856 | public UUID ObjectCreator | ||
857 | { | ||
858 | get { return _creatorID; } | ||
859 | } | ||
860 | |||
861 | public UUID ObjectOwner | ||
862 | { | ||
863 | get { return _ownerID; } | ||
864 | } | ||
865 | |||
866 | public SceneObjectGroup ParentGroup | 856 | public SceneObjectGroup ParentGroup |
867 | { | 857 | { |
868 | get { return m_parentGroup; } | 858 | get { return m_parentGroup; } |
@@ -1440,7 +1430,7 @@ if (m_shape != null) { | |||
1440 | // Move afterwards ResetIDs as it clears the localID | 1430 | // Move afterwards ResetIDs as it clears the localID |
1441 | dupe.LocalId = localID; | 1431 | dupe.LocalId = localID; |
1442 | // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated. | 1432 | // This may be wrong... it might have to be applied in SceneObjectGroup to the object that's being duplicated. |
1443 | dupe._lastOwnerID = ObjectOwner; | 1433 | dupe._lastOwnerID = OwnerID; |
1444 | 1434 | ||
1445 | byte[] extraP = new byte[Shape.ExtraParams.Length]; | 1435 | byte[] extraP = new byte[Shape.ExtraParams.Length]; |
1446 | Array.Copy(Shape.ExtraParams, extraP, extraP.Length); | 1436 | Array.Copy(Shape.ExtraParams, extraP, extraP.Length); |
@@ -2410,10 +2400,10 @@ if (m_shape != null) { | |||
2410 | //isattachment = ParentGroup.RootPart.IsAttachment; | 2400 | //isattachment = ParentGroup.RootPart.IsAttachment; |
2411 | 2401 | ||
2412 | byte[] color = new byte[] {m_color.R, m_color.G, m_color.B, m_color.A}; | 2402 | byte[] color = new byte[] {m_color.R, m_color.G, m_color.B, m_color.A}; |
2413 | remoteClient.SendPrimitiveToClient(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, m_shape, | 2403 | remoteClient.SendPrimitiveToClient(new SendPrimitiveData(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, m_shape, |
2414 | lPos, Velocity, Acceleration, RotationOffset, RotationalVelocity, clientFlags, m_uuid, _ownerID, | 2404 | lPos, Velocity, Acceleration, RotationOffset, RotationalVelocity, clientFlags, m_uuid, _ownerID, |
2415 | m_text, color, _parentID, m_particleSystem, m_clickAction, (byte)m_material, m_TextureAnimation, IsAttachment, | 2405 | m_text, color, _parentID, m_particleSystem, m_clickAction, (byte)m_material, m_TextureAnimation, IsAttachment, |
2416 | AttachmentPoint,FromItemID, Sound, SoundGain, SoundFlags, SoundRadius); | 2406 | AttachmentPoint,FromItemID, Sound, SoundGain, SoundFlags, SoundRadius, ParentGroup.GetUpdatePriority(remoteClient))); |
2417 | } | 2407 | } |
2418 | 2408 | ||
2419 | /// <summary> | 2409 | /// <summary> |
@@ -3804,12 +3794,12 @@ if (m_shape != null) { | |||
3804 | 3794 | ||
3805 | // Causes this thread to dig into the Client Thread Data. | 3795 | // Causes this thread to dig into the Client Thread Data. |
3806 | // Remember your locking here! | 3796 | // Remember your locking here! |
3807 | remoteClient.SendPrimTerseUpdate(m_regionHandle, | 3797 | remoteClient.SendPrimTerseUpdate(new SendPrimitiveTerseData(m_regionHandle, |
3808 | (ushort)(m_parentGroup.GetTimeDilation() * | 3798 | (ushort)(m_parentGroup.GetTimeDilation() * |
3809 | (float)ushort.MaxValue), LocalId, lPos, | 3799 | (float)ushort.MaxValue), LocalId, lPos, |
3810 | RotationOffset, Velocity, | 3800 | RotationOffset, Velocity, |
3811 | RotationalVelocity, state, FromItemID, | 3801 | RotationalVelocity, state, FromItemID, |
3812 | OwnerID, (int)AttachmentPoint); | 3802 | OwnerID, (int)AttachmentPoint, ParentGroup.GetUpdatePriority(remoteClient))); |
3813 | } | 3803 | } |
3814 | 3804 | ||
3815 | public void AddScriptLPS(int count) | 3805 | public void AddScriptLPS(int count) |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index b468dde..973537e 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -403,12 +403,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
403 | set { m_parentPosition = value; } | 403 | set { m_parentPosition = value; } |
404 | } | 404 | } |
405 | 405 | ||
406 | public int MaxPrimsPerFrame | ||
407 | { | ||
408 | get { return m_sceneViewer.MaxPrimsPerFrame; } | ||
409 | set { m_sceneViewer.MaxPrimsPerFrame = value; } | ||
410 | } | ||
411 | |||
412 | /// <summary> | 406 | /// <summary> |
413 | /// Absolute position of this avatar in 'region cordinates' | 407 | /// Absolute position of this avatar in 'region cordinates' |
414 | /// </summary> | 408 | /// </summary> |
@@ -2456,11 +2450,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
2456 | m_perfMonMS = Environment.TickCount; | 2450 | m_perfMonMS = Environment.TickCount; |
2457 | 2451 | ||
2458 | Vector3 pos = m_pos; | 2452 | Vector3 pos = m_pos; |
2459 | Vector3 vel = Velocity; | ||
2460 | Quaternion rot = m_bodyRot; | ||
2461 | pos.Z -= m_appearance.HipOffset; | 2453 | 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), | 2454 | |
2463 | new Vector3(vel.X, vel.Y, vel.Z), rot, m_uuid); | 2455 | remoteClient.SendAvatarTerseUpdate(new SendAvatarTerseData(m_regionHandle, (ushort)(m_scene.TimeDilation * ushort.MaxValue), LocalId, |
2456 | pos, m_velocity, m_rotation, m_uuid, GetUpdatePriority(remoteClient))); | ||
2464 | 2457 | ||
2465 | m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); | 2458 | m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS); |
2466 | m_scene.StatsReporter.AddAgentUpdates(1); | 2459 | m_scene.StatsReporter.AddAgentUpdates(1); |
@@ -2474,7 +2467,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2474 | { | 2467 | { |
2475 | m_perfMonMS = Environment.TickCount; | 2468 | m_perfMonMS = Environment.TickCount; |
2476 | 2469 | ||
2477 | m_scene.Broadcast(SendTerseUpdateToClient); | 2470 | m_scene.ForEachClient(SendTerseUpdateToClient); |
2478 | 2471 | ||
2479 | m_lastVelocity = m_velocity; | 2472 | m_lastVelocity = m_velocity; |
2480 | lastPhysPos = AbsolutePosition; | 2473 | lastPhysPos = AbsolutePosition; |
@@ -2566,9 +2559,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
2566 | Vector3 pos = m_pos; | 2559 | Vector3 pos = m_pos; |
2567 | pos.Z -= m_appearance.HipOffset; | 2560 | pos.Z -= m_appearance.HipOffset; |
2568 | 2561 | ||
2569 | remoteAvatar.m_controllingClient.SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, | 2562 | 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(), | 2563 | LocalId, m_pos, m_appearance.Texture.GetBytes(), |
2571 | m_parentID, rot); | 2564 | m_parentID, rot)); |
2572 | m_scene.StatsReporter.AddAgentUpdates(1); | 2565 | m_scene.StatsReporter.AddAgentUpdates(1); |
2573 | } | 2566 | } |
2574 | 2567 | ||
@@ -2637,8 +2630,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
2637 | Vector3 pos = m_pos; | 2630 | Vector3 pos = m_pos; |
2638 | pos.Z -= m_appearance.HipOffset; | 2631 | pos.Z -= m_appearance.HipOffset; |
2639 | 2632 | ||
2640 | m_controllingClient.SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, | 2633 | 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); | 2634 | m_pos, m_appearance.Texture.GetBytes(), m_parentID, rot)); |
2642 | 2635 | ||
2643 | if (!m_isChildAgent) | 2636 | if (!m_isChildAgent) |
2644 | { | 2637 | { |
@@ -2744,8 +2737,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
2744 | } | 2737 | } |
2745 | 2738 | ||
2746 | Quaternion rot = m_bodyRot; | 2739 | Quaternion rot = m_bodyRot; |
2747 | m_controllingClient.SendAvatarData(m_regionInfo.RegionHandle, m_firstname, m_lastname, m_grouptitle, m_uuid, LocalId, | 2740 | 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); | 2741 | m_pos, m_appearance.Texture.GetBytes(), m_parentID, rot)); |
2749 | 2742 | ||
2750 | } | 2743 | } |
2751 | 2744 | ||
@@ -2776,7 +2769,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2776 | if (m_isChildAgent) | 2769 | if (m_isChildAgent) |
2777 | return; | 2770 | return; |
2778 | 2771 | ||
2779 | m_scene.Broadcast( | 2772 | m_scene.ForEachClient( |
2780 | delegate(IClientAPI client) { client.SendAnimations(animations, seqs, m_controllingClient.AgentId, objectIDs); }); | 2773 | delegate(IClientAPI client) { client.SendAnimations(animations, seqs, m_controllingClient.AgentId, objectIDs); }); |
2781 | } | 2774 | } |
2782 | 2775 | ||
@@ -3882,5 +3875,41 @@ namespace OpenSim.Region.Framework.Scenes | |||
3882 | } | 3875 | } |
3883 | } | 3876 | } |
3884 | } | 3877 | } |
3878 | |||
3879 | public double GetUpdatePriority(IClientAPI client) | ||
3880 | { | ||
3881 | switch (Scene.UpdatePrioritizationScheme) | ||
3882 | { | ||
3883 | case Scene.UpdatePrioritizationSchemes.Time: | ||
3884 | return GetPriorityByTime(); | ||
3885 | case Scene.UpdatePrioritizationSchemes.Distance: | ||
3886 | return GetPriorityByDistance(client); | ||
3887 | case Scene.UpdatePrioritizationSchemes.SimpleAngularDistance: | ||
3888 | return GetPriorityByDistance(client); | ||
3889 | default: | ||
3890 | throw new InvalidOperationException("UpdatePrioritizationScheme not defined."); | ||
3891 | } | ||
3892 | } | ||
3893 | |||
3894 | private double GetPriorityByTime() | ||
3895 | { | ||
3896 | return DateTime.Now.ToOADate(); | ||
3897 | } | ||
3898 | |||
3899 | private double GetPriorityByDistance(IClientAPI client) | ||
3900 | { | ||
3901 | ScenePresence presence = Scene.GetScenePresence(client.AgentId); | ||
3902 | if (presence != null) | ||
3903 | { | ||
3904 | return GetPriorityByDistance((presence.IsChildAgent) ? | ||
3905 | presence.AbsolutePosition : presence.CameraPosition); | ||
3906 | } | ||
3907 | return double.NaN; | ||
3908 | } | ||
3909 | |||
3910 | private double GetPriorityByDistance(Vector3 position) | ||
3911 | { | ||
3912 | return Vector3.Distance(AbsolutePosition, position); | ||
3913 | } | ||
3885 | } | 3914 | } |
3886 | } | 3915 | } |
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 a8acf0d..8ad9327 100644 --- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs +++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs | |||
@@ -1011,12 +1011,12 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
1011 | 1011 | ||
1012 | } | 1012 | } |
1013 | 1013 | ||
1014 | public void SendAvatarData(ulong regionHandle, string firstName, string lastName, string grouptitle, UUID avatarID, uint avatarLocalID, Vector3 Pos, byte[] textureEntry, uint parentID, Quaternion rotation) | 1014 | public void SendAvatarData(SendAvatarData data) |
1015 | { | 1015 | { |
1016 | 1016 | ||
1017 | } | 1017 | } |
1018 | 1018 | ||
1019 | public void SendAvatarTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, Vector3 position, Vector3 velocity, Quaternion rotation, UUID agentid) | 1019 | public void SendAvatarTerseUpdate(SendAvatarTerseData data) |
1020 | { | 1020 | { |
1021 | 1021 | ||
1022 | } | 1022 | } |
@@ -1036,17 +1036,12 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server | |||
1036 | 1036 | ||
1037 | } | 1037 | } |
1038 | 1038 | ||
1039 | 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) | 1039 | public void SendPrimitiveToClient(SendPrimitiveData data) |
1040 | { | 1040 | { |
1041 | 1041 | ||
1042 | } | 1042 | } |
1043 | 1043 | ||
1044 | 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) | 1044 | public void SendPrimTerseUpdate(SendPrimitiveTerseData data) |
1045 | { | ||
1046 | |||
1047 | } | ||
1048 | |||
1049 | 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) | ||
1050 | { | 1045 | { |
1051 | 1046 | ||
1052 | } | 1047 | } |
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..6c58f2d 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,11 @@ 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 | { | ||
629 | } | ||
630 | public virtual void SendPrimTerseUpdate(ulong regionHandle, ushort timeDilation, uint localID, | ||
631 | Vector3 position, Quaternion rotation, Vector3 velocity, | ||
632 | Vector3 rotationalvelocity, byte state, UUID AssetId, UUID ownerID, int attachPoint) | ||
633 | { | 616 | { |
634 | } | 617 | } |
635 | 618 | ||
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index e10e612..57b14f7 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -2875,7 +2875,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2875 | { | 2875 | { |
2876 | m_host.AddScriptLPS(1); | 2876 | m_host.AddScriptLPS(1); |
2877 | 2877 | ||
2878 | return m_host.ObjectOwner.ToString(); | 2878 | return m_host.OwnerID.ToString(); |
2879 | } | 2879 | } |
2880 | 2880 | ||
2881 | public void llInstantMessage(string user, string message) | 2881 | public void llInstantMessage(string user, string message) |
@@ -5634,7 +5634,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
5634 | ILandObject parcel = World.LandChannel.GetLandObject(av.AbsolutePosition.X, av.AbsolutePosition.Y); | 5634 | ILandObject parcel = World.LandChannel.GetLandObject(av.AbsolutePosition.X, av.AbsolutePosition.Y); |
5635 | if (parcel != null) | 5635 | if (parcel != null) |
5636 | { | 5636 | { |
5637 | if (m_host.ObjectOwner == parcel.LandData.OwnerID || | 5637 | if (m_host.OwnerID == parcel.LandData.OwnerID || |
5638 | (m_host.OwnerID == m_host.GroupID && m_host.GroupID == parcel.LandData.GroupID | 5638 | (m_host.OwnerID == m_host.GroupID && m_host.GroupID == parcel.LandData.GroupID |
5639 | && parcel.LandData.IsGroupOwned) || World.Permissions.IsGod(m_host.OwnerID)) | 5639 | && parcel.LandData.IsGroupOwned) || World.Permissions.IsGod(m_host.OwnerID)) |
5640 | { | 5640 | { |
@@ -7157,7 +7157,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7157 | 7157 | ||
7158 | ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); | 7158 | ILandObject land = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); |
7159 | 7159 | ||
7160 | if (land.LandData.OwnerID != m_host.ObjectOwner) | 7160 | if (land.LandData.OwnerID != m_host.OwnerID) |
7161 | return; | 7161 | return; |
7162 | 7162 | ||
7163 | land.SetMusicUrl(url); | 7163 | land.SetMusicUrl(url); |
@@ -7215,7 +7215,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
7215 | public LSL_String llGetCreator() | 7215 | public LSL_String llGetCreator() |
7216 | { | 7216 | { |
7217 | m_host.AddScriptLPS(1); | 7217 | m_host.AddScriptLPS(1); |
7218 | return m_host.ObjectCreator.ToString(); | 7218 | return m_host.CreatorID.ToString(); |
7219 | } | 7219 | } |
7220 | 7220 | ||
7221 | public LSL_String llGetTimestamp() | 7221 | public LSL_String llGetTimestamp() |
@@ -8396,7 +8396,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
8396 | IDialogModule dm = World.RequestModuleInterface<IDialogModule>(); | 8396 | IDialogModule dm = World.RequestModuleInterface<IDialogModule>(); |
8397 | if (null != dm) | 8397 | if (null != dm) |
8398 | dm.SendUrlToUser( | 8398 | dm.SendUrlToUser( |
8399 | new UUID(avatar_id), m_host.Name, m_host.UUID, m_host.ObjectOwner, false, message, url); | 8399 | new UUID(avatar_id), m_host.Name, m_host.UUID, m_host.OwnerID, false, message, url); |
8400 | 8400 | ||
8401 | ConditionalScriptSleep(10000); | 8401 | ConditionalScriptSleep(10000); |
8402 | } | 8402 | } |
@@ -8411,7 +8411,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
8411 | // according to the docs, this command only works if script owner and land owner are the same | 8411 | // according to the docs, this command only works if script owner and land owner are the same |
8412 | // lets add estate owners and gods, too, and use the generic permission check. | 8412 | // lets add estate owners and gods, too, and use the generic permission check. |
8413 | ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); | 8413 | ILandObject landObject = World.LandChannel.GetLandObject(m_host.AbsolutePosition.X, m_host.AbsolutePosition.Y); |
8414 | if (!World.Permissions.CanEditParcel(m_host.ObjectOwner, landObject)) return; | 8414 | if (!World.Permissions.CanEditParcel(m_host.OwnerID, landObject)) return; |
8415 | 8415 | ||
8416 | bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)? | 8416 | bool update = false; // send a ParcelMediaUpdate (and possibly change the land's media URL)? |
8417 | byte loop = 0; | 8417 | byte loop = 0; |
@@ -9081,9 +9081,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
9081 | Vector3 velocity = m_host.Velocity; | 9081 | Vector3 velocity = m_host.Velocity; |
9082 | Quaternion rotation = m_host.RotationOffset; | 9082 | Quaternion rotation = m_host.RotationOffset; |
9083 | string ownerName = String.Empty; | 9083 | string ownerName = String.Empty; |
9084 | ScenePresence scenePresence = World.GetScenePresence(m_host.ObjectOwner); | 9084 | ScenePresence scenePresence = World.GetScenePresence(m_host.OwnerID); |
9085 | if (scenePresence == null) | 9085 | if (scenePresence == null) |
9086 | ownerName = resolveName(m_host.ObjectOwner); | 9086 | ownerName = resolveName(m_host.OwnerID); |
9087 | else | 9087 | else |
9088 | ownerName = scenePresence.Name; | 9088 | ownerName = scenePresence.Name; |
9089 | 9089 | ||
@@ -9108,7 +9108,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
9108 | httpHeaders["X-SecondLife-Local-Velocity"] = string.Format("({0:0.000000}, {1:0.000000}, {2:0.000000})", velocity.X, velocity.Y, velocity.Z); | 9108 | httpHeaders["X-SecondLife-Local-Velocity"] = string.Format("({0:0.000000}, {1:0.000000}, {2:0.000000})", velocity.X, velocity.Y, velocity.Z); |
9109 | 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); | 9109 | 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); |
9110 | httpHeaders["X-SecondLife-Owner-Name"] = ownerName; | 9110 | httpHeaders["X-SecondLife-Owner-Name"] = ownerName; |
9111 | httpHeaders["X-SecondLife-Owner-Key"] = m_host.ObjectOwner.ToString(); | 9111 | httpHeaders["X-SecondLife-Owner-Key"] = m_host.OwnerID.ToString(); |
9112 | string userAgent = config.Configs["Network"].GetString("user_agent", null); | 9112 | string userAgent = config.Configs["Network"].GetString("user_agent", null); |
9113 | if (userAgent != null) | 9113 | if (userAgent != null) |
9114 | httpHeaders["User-Agent"] = userAgent; | 9114 | httpHeaders["User-Agent"] = userAgent; |
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; |