diff options
Diffstat (limited to 'OpenSim/Region/ClientStack')
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 229 |
1 files changed, 228 insertions, 1 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 8487adc..82a2cdd 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> |
@@ -3159,6 +3197,195 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3159 | 3197 | ||
3160 | #endregion | 3198 | #endregion |
3161 | 3199 | ||
3200 | #region Prim/Avatar Updates | ||
3201 | |||
3202 | /*void SendObjectUpdate(SceneObjectPart obj, PrimFlags creatorFlags, PrimUpdateFlags updateFlags) | ||
3203 | { | ||
3204 | bool canUseCompressed, canUseImproved; | ||
3205 | UpdateFlagsToPacketType(creatorFlags, updateFlags, out canUseCompressed, out canUseImproved); | ||
3206 | |||
3207 | if (!canUseImproved && !canUseCompressed) | ||
3208 | SendFullObjectUpdate(obj, creatorFlags, updateFlags); | ||
3209 | else if (!canUseImproved) | ||
3210 | SendObjectUpdateCompressed(obj, creatorFlags, updateFlags); | ||
3211 | else | ||
3212 | SendImprovedTerseObjectUpdate(obj, creatorFlags, updateFlags); | ||
3213 | } | ||
3214 | |||
3215 | void SendFullObjectUpdate(SceneObjectPart obj, PrimFlags creatorFlags, PrimUpdateFlags updateFlags) | ||
3216 | { | ||
3217 | IClientAPI owner; | ||
3218 | if (m_scene.ClientManager.TryGetValue(obj.OwnerID, out owner) && owner is LLClientView) | ||
3219 | { | ||
3220 | LLClientView llOwner = (LLClientView)owner; | ||
3221 | |||
3222 | // Send an update out to the owner | ||
3223 | ObjectUpdatePacket updateToOwner = new ObjectUpdatePacket(); | ||
3224 | updateToOwner.RegionData.RegionHandle = obj.RegionHandle; | ||
3225 | //updateToOwner.RegionData.TimeDilation = (ushort)(timeDilation * (float)UInt16.MaxValue); | ||
3226 | updateToOwner.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; | ||
3227 | updateToOwner.ObjectData[0] = BuildUpdateBlock(obj, obj.Flags | creatorFlags | PrimFlags.ObjectYouOwner, 0); | ||
3228 | |||
3229 | m_udpServer.SendPacket(llOwner.UDPClient, updateToOwner, ThrottleOutPacketType.State, true); | ||
3230 | } | ||
3231 | |||
3232 | // Send an update out to everyone else | ||
3233 | ObjectUpdatePacket updateToOthers = new ObjectUpdatePacket(); | ||
3234 | updateToOthers.RegionData.RegionHandle = obj.RegionHandle; | ||
3235 | //updateToOthers.RegionData.TimeDilation = (ushort)(timeDilation * (float)UInt16.MaxValue); | ||
3236 | updateToOthers.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; | ||
3237 | updateToOthers.ObjectData[0] = BuildUpdateBlock(obj, obj.Flags, 0); | ||
3238 | |||
3239 | m_scene.ClientManager.ForEach( | ||
3240 | delegate(IClientAPI client) | ||
3241 | { | ||
3242 | if (client.AgentId != obj.OwnerID && client is LLClientView) | ||
3243 | { | ||
3244 | LLClientView llClient = (LLClientView)client; | ||
3245 | m_udpServer.SendPacket(llClient.UDPClient, updateToOthers, ThrottleOutPacketType.State, true); | ||
3246 | } | ||
3247 | } | ||
3248 | ); | ||
3249 | } | ||
3250 | |||
3251 | void SendObjectUpdateCompressed(SceneObjectPart obj, PrimFlags creatorFlags, PrimUpdateFlags updateFlags) | ||
3252 | { | ||
3253 | } | ||
3254 | |||
3255 | void SendImprovedTerseObjectUpdate(SceneObjectPart obj, PrimFlags creatorFlags, PrimUpdateFlags updateFlags) | ||
3256 | { | ||
3257 | } | ||
3258 | |||
3259 | void UpdateFlagsToPacketType(PrimFlags creatorFlags, PrimUpdateFlags updateFlags, out bool canUseCompressed, out bool canUseImproved) | ||
3260 | { | ||
3261 | canUseCompressed = true; | ||
3262 | canUseImproved = true; | ||
3263 | |||
3264 | if ((updateFlags & PrimUpdateFlags.FullUpdate) == PrimUpdateFlags.FullUpdate || creatorFlags != PrimFlags.None) | ||
3265 | { | ||
3266 | canUseCompressed = false; | ||
3267 | canUseImproved = false; | ||
3268 | } | ||
3269 | else | ||
3270 | { | ||
3271 | if ((updateFlags & PrimUpdateFlags.Velocity) != 0 || | ||
3272 | (updateFlags & PrimUpdateFlags.Acceleration) != 0 || | ||
3273 | (updateFlags & PrimUpdateFlags.CollisionPlane) != 0 || | ||
3274 | (updateFlags & PrimUpdateFlags.Joint) != 0) | ||
3275 | { | ||
3276 | canUseCompressed = false; | ||
3277 | } | ||
3278 | |||
3279 | if ((updateFlags & PrimUpdateFlags.PrimFlags) != 0 || | ||
3280 | (updateFlags & PrimUpdateFlags.ParentID) != 0 || | ||
3281 | (updateFlags & PrimUpdateFlags.Scale) != 0 || | ||
3282 | (updateFlags & PrimUpdateFlags.PrimData) != 0 || | ||
3283 | (updateFlags & PrimUpdateFlags.Text) != 0 || | ||
3284 | (updateFlags & PrimUpdateFlags.NameValue) != 0 || | ||
3285 | (updateFlags & PrimUpdateFlags.ExtraData) != 0 || | ||
3286 | (updateFlags & PrimUpdateFlags.TextureAnim) != 0 || | ||
3287 | (updateFlags & PrimUpdateFlags.Sound) != 0 || | ||
3288 | (updateFlags & PrimUpdateFlags.Particles) != 0 || | ||
3289 | (updateFlags & PrimUpdateFlags.Material) != 0 || | ||
3290 | (updateFlags & PrimUpdateFlags.ClickAction) != 0 || | ||
3291 | (updateFlags & PrimUpdateFlags.MediaURL) != 0 || | ||
3292 | (updateFlags & PrimUpdateFlags.Joint) != 0) | ||
3293 | { | ||
3294 | canUseImproved = false; | ||
3295 | } | ||
3296 | } | ||
3297 | } | ||
3298 | |||
3299 | static ObjectUpdatePacket.ObjectDataBlock BuildUpdateBlockFromPrim(SceneObjectPart prim, UUID assetID, PrimFlags flags, uint crc) | ||
3300 | { | ||
3301 | byte[] objectData = new byte[60]; | ||
3302 | prim.OffsetPosition.ToBytes(objectData, 0); | ||
3303 | prim.Velocity.ToBytes(objectData, 12); | ||
3304 | prim.Acceleration.ToBytes(objectData, 24); | ||
3305 | prim.RotationOffset.ToBytes(objectData, 36); | ||
3306 | prim.AngularVelocity.ToBytes(objectData, 48); | ||
3307 | |||
3308 | ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); | ||
3309 | update.ClickAction = (byte)prim.ClickAction; | ||
3310 | update.CRC = crc; | ||
3311 | update.ExtraParams = prim.Shape.ExtraParams ?? Utils.EmptyBytes; | ||
3312 | update.Flags = (byte)flags; | ||
3313 | update.FullID = prim.UUID; | ||
3314 | update.ID = prim.LocalId; | ||
3315 | //update.JointAxisOrAnchor = Vector3.Zero; // These are deprecated | ||
3316 | //update.JointPivot = Vector3.Zero; | ||
3317 | //update.JointType = 0; | ||
3318 | update.Material = prim.Material; | ||
3319 | update.MediaURL = Utils.EmptyBytes; // FIXME: Support this in OpenSim | ||
3320 | if (prim.IsAttachment) | ||
3321 | update.NameValue = Util.StringToBytes256("AttachItemID STRING RW SV " + assetID); | ||
3322 | else | ||
3323 | update.NameValue = Utils.EmptyBytes; | ||
3324 | update.ObjectData = objectData; | ||
3325 | update.ParentID = prim.ParentID; | ||
3326 | update.PathBegin = prim.Shape.PathBegin; | ||
3327 | update.PathCurve = prim.Shape.PathCurve; | ||
3328 | update.PathEnd = prim.Shape.PathEnd; | ||
3329 | update.PathRadiusOffset = prim.Shape.PathRadiusOffset; | ||
3330 | update.PathRevolutions = prim.Shape.PathRevolutions; | ||
3331 | update.PathScaleX = prim.Shape.PathScaleX; | ||
3332 | update.PathScaleY = prim.Shape.PathScaleY; | ||
3333 | update.PathShearX = prim.Shape.PathShearX; | ||
3334 | update.PathShearY = prim.Shape.PathShearY; | ||
3335 | update.PathSkew = prim.Shape.PathSkew; | ||
3336 | update.PathTaperX = prim.Shape.PathTaperX; | ||
3337 | update.PathTaperY = prim.Shape.PathTaperY; | ||
3338 | update.PathTwist = prim.Shape.PathTwist; | ||
3339 | update.PathTwistBegin = prim.Shape.PathTwistBegin; | ||
3340 | update.PCode = prim.Shape.PCode; | ||
3341 | update.ProfileBegin = prim.Shape.ProfileBegin; | ||
3342 | update.ProfileCurve = prim.Shape.ProfileCurve; | ||
3343 | update.ProfileEnd = prim.Shape.ProfileEnd; | ||
3344 | update.ProfileHollow = prim.Shape.ProfileHollow; | ||
3345 | update.PSBlock = prim.ParticleSystem ?? Utils.EmptyBytes; | ||
3346 | update.TextColor = new Color4(prim.Color).GetBytes(true); | ||
3347 | update.TextureAnim = prim.TextureAnimation ?? Utils.EmptyBytes; | ||
3348 | update.TextureEntry = prim.Shape.TextureEntry ?? Utils.EmptyBytes; | ||
3349 | update.Scale = prim.Scale; | ||
3350 | update.State = prim.Shape.State; | ||
3351 | update.Text = Util.StringToBytes256(prim.Text); | ||
3352 | update.UpdateFlags = (uint)flags; | ||
3353 | |||
3354 | if (prim.Sound != UUID.Zero) | ||
3355 | { | ||
3356 | update.Sound = prim.Sound; | ||
3357 | update.OwnerID = prim.OwnerID; | ||
3358 | update.Gain = (float)prim.SoundGain; | ||
3359 | update.Radius = (float)prim.SoundRadius; | ||
3360 | } | ||
3361 | |||
3362 | switch ((PCode)prim.Shape.PCode) | ||
3363 | { | ||
3364 | case PCode.Grass: | ||
3365 | case PCode.Tree: | ||
3366 | case PCode.NewTree: | ||
3367 | update.Data = new byte[] { prim.Shape.State }; | ||
3368 | break; | ||
3369 | default: | ||
3370 | // TODO: Support ScratchPad | ||
3371 | //if (prim.ScratchPad != null) | ||
3372 | //{ | ||
3373 | // update.Data = new byte[prim.ScratchPad.Length]; | ||
3374 | // Buffer.BlockCopy(prim.ScratchPad, 0, update.Data, 0, update.Data.Length); | ||
3375 | //} | ||
3376 | //else | ||
3377 | //{ | ||
3378 | // update.Data = Utils.EmptyBytes; | ||
3379 | //} | ||
3380 | update.Data = Utils.EmptyBytes; | ||
3381 | break; | ||
3382 | } | ||
3383 | |||
3384 | return update; | ||
3385 | }*/ | ||
3386 | |||
3387 | #endregion Prim/Avatar Updates | ||
3388 | |||
3162 | #region Avatar Packet/data sending Methods | 3389 | #region Avatar Packet/data sending Methods |
3163 | 3390 | ||
3164 | /// <summary> | 3391 | /// <summary> |
@@ -3365,7 +3592,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3365 | return; | 3592 | return; |
3366 | if (primShape.PCode == 9 && primShape.State != 0 && parentID == 0) | 3593 | if (primShape.PCode == 9 && primShape.State != 0 && parentID == 0) |
3367 | return; | 3594 | return; |
3368 | 3595 | ||
3369 | if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0) | 3596 | if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0) |
3370 | rotation = Quaternion.Identity; | 3597 | rotation = Quaternion.Identity; |
3371 | 3598 | ||