diff options
Diffstat (limited to 'OpenSim/Region/ClientStack')
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | 259 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/Linden/UDP/LLUDPZeroEncoder.cs | 2 |
2 files changed, 227 insertions, 34 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index dd06e40..4158adc 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs | |||
@@ -3884,44 +3884,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3884 | /// </summary> | 3884 | /// </summary> |
3885 | public void SendEntityFullUpdateImmediate(ISceneEntity ent) | 3885 | public void SendEntityFullUpdateImmediate(ISceneEntity ent) |
3886 | { | 3886 | { |
3887 | // m_log.DebugFormat( | 3887 | if (ent == null || (!(ent is ScenePresence) && !(ent is SceneObjectPart))) |
3888 | // "[LLCLIENTVIEW]: Sending immediate object update for avatar {0} {1} to {2} {3}", | ||
3889 | // avatar.Name, avatar.UUID, Name, AgentId); | ||
3890 | |||
3891 | if (ent == null) | ||
3892 | return; | 3888 | return; |
3893 | 3889 | ||
3894 | if (ent is ScenePresence) | 3890 | UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); |
3895 | { | 3891 | Buffer.BlockCopy(objectUpdateHeader, 0, buf.Data, 0, 7); |
3896 | ScenePresence presence = ent as ScenePresence; | ||
3897 | UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint); | ||
3898 | 3892 | ||
3899 | Buffer.BlockCopy(objectUpdateHeader, 0, buf.Data, 0, 7); | 3893 | LLUDPZeroEncoder zc = new LLUDPZeroEncoder(buf.Data); |
3894 | zc.Position = 7; | ||
3900 | 3895 | ||
3901 | LLUDPZeroEncoder zc = new LLUDPZeroEncoder(buf.Data); | 3896 | zc.AddUInt64(m_scene.RegionInfo.RegionHandle); |
3902 | zc.Position = 7; | 3897 | zc.AddUInt16(Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f)); |
3903 | zc.AddUInt64(m_scene.RegionInfo.RegionHandle); | ||
3904 | zc.AddUInt16(Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f)); | ||
3905 | zc.AddByte(1); // block count | ||
3906 | CreateAvatarUpdateBlock(presence, zc); | ||
3907 | buf.DataLength = zc.Finish(); | ||
3908 | m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority, null, false, false); | ||
3909 | } | ||
3910 | else if(ent is SceneObjectPart) | ||
3911 | { | ||
3912 | ObjectUpdatePacket objupdate = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); | ||
3913 | objupdate.RegionData.TimeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f); | ||
3914 | objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; | ||
3915 | 3898 | ||
3916 | SceneObjectPart part = ent as SceneObjectPart; | 3899 | zc.AddByte(1); // block count |
3917 | objupdate.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; | ||
3918 | objupdate.ObjectData[0] = CreatePrimUpdateBlock(part, (ScenePresence)SceneAgent); | ||
3919 | 3900 | ||
3920 | OutPacket(objupdate, ThrottleOutPacketType.Task); | 3901 | if (ent is ScenePresence) |
3921 | } | 3902 | CreateAvatarUpdateBlock(ent as ScenePresence, zc); |
3903 | else | ||
3904 | CreatePrimUpdateBlock(ent as SceneObjectPart, (ScenePresence)SceneAgent, zc); | ||
3922 | 3905 | ||
3923 | // We need to record the avatar local id since the root prim of an attachment points to this. | 3906 | buf.DataLength = zc.Finish(); |
3924 | // m_attachmentsSent.Add(avatar.LocalId); | 3907 | m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority, null, false, false); |
3925 | } | 3908 | } |
3926 | 3909 | ||
3927 | public void SendEntityTerseUpdateImmediate(ISceneEntity ent) | 3910 | public void SendEntityTerseUpdateImmediate(ISceneEntity ent) |
@@ -6050,8 +6033,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6050 | zc.AddZeros(lastzeros); | 6033 | zc.AddZeros(lastzeros); |
6051 | } | 6034 | } |
6052 | 6035 | ||
6053 | |||
6054 | // protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart data, UUID recipientID) | ||
6055 | protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart part, ScenePresence sp) | 6036 | protected ObjectUpdatePacket.ObjectDataBlock CreatePrimUpdateBlock(SceneObjectPart part, ScenePresence sp) |
6056 | { | 6037 | { |
6057 | byte[] objectData = new byte[60]; | 6038 | byte[] objectData = new byte[60]; |
@@ -6193,6 +6174,218 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6193 | return update; | 6174 | return update; |
6194 | } | 6175 | } |
6195 | 6176 | ||
6177 | protected void CreatePrimUpdateBlock(SceneObjectPart part, ScenePresence sp, LLUDPZeroEncoder zc) | ||
6178 | { | ||
6179 | // prepare data | ||
6180 | |||
6181 | //NameValue and state | ||
6182 | byte[] nv = null; | ||
6183 | byte state; | ||
6184 | if (part.ParentGroup.IsAttachment) | ||
6185 | { | ||
6186 | if (part.IsRoot) | ||
6187 | nv = Util.StringToBytes256("AttachItemID STRING RW SV " + part.ParentGroup.FromItemID); | ||
6188 | |||
6189 | int st = (int)part.ParentGroup.AttachmentPoint; | ||
6190 | state = (byte)(((st & 0xf0) >> 4) + ((st & 0x0f) << 4)); ; | ||
6191 | } | ||
6192 | else | ||
6193 | state = part.Shape.State; // not sure about this | ||
6194 | |||
6195 | #region PrimFlags | ||
6196 | // prim/update flags | ||
6197 | PrimFlags primflags = (PrimFlags)m_scene.Permissions.GenerateClientFlags(part, sp); | ||
6198 | // Don't send the CreateSelected flag to everyone | ||
6199 | primflags &= ~PrimFlags.CreateSelected; | ||
6200 | if (sp.UUID == part.OwnerID) | ||
6201 | { | ||
6202 | if (part.CreateSelected) | ||
6203 | { | ||
6204 | // Only send this flag once, then unset it | ||
6205 | primflags |= PrimFlags.CreateSelected; | ||
6206 | part.CreateSelected = false; | ||
6207 | } | ||
6208 | } | ||
6209 | #endregion PrimFlags | ||
6210 | |||
6211 | // filter out mesh faces hack | ||
6212 | ushort profileBegin = part.Shape.ProfileBegin; | ||
6213 | ushort profileHollow = part.Shape.ProfileHollow; | ||
6214 | byte profileCurve = part.Shape.ProfileCurve; | ||
6215 | byte pathScaleY = part.Shape.PathScaleY; | ||
6216 | |||
6217 | if (part.Shape.SculptType == (byte)SculptType.Mesh) // filter out hack | ||
6218 | { | ||
6219 | profileCurve = (byte)(part.Shape.ProfileCurve & 0x0f); | ||
6220 | // fix old values that confused viewers | ||
6221 | if (profileBegin == 1) | ||
6222 | profileBegin = 9375; | ||
6223 | if (profileHollow == 1) | ||
6224 | profileHollow = 27500; | ||
6225 | // fix torus hole size Y that also confuse some viewers | ||
6226 | if (profileCurve == (byte)ProfileShape.Circle && pathScaleY < 150) | ||
6227 | pathScaleY = 150; | ||
6228 | } | ||
6229 | |||
6230 | // data block | ||
6231 | byte[] data = null; | ||
6232 | switch ((PCode)part.Shape.PCode) | ||
6233 | { | ||
6234 | case PCode.Grass: | ||
6235 | case PCode.Tree: | ||
6236 | case PCode.NewTree: | ||
6237 | data = new byte[] { part.Shape.State }; | ||
6238 | break; | ||
6239 | default: | ||
6240 | break; | ||
6241 | } | ||
6242 | |||
6243 | // do encode the things | ||
6244 | zc.AddUInt(part.LocalId); | ||
6245 | zc.AddByte(state); // state | ||
6246 | zc.AddUUID(part.UUID); | ||
6247 | zc.AddZeros(4); // crc unused | ||
6248 | zc.AddByte(part.Shape.PCode); | ||
6249 | zc.AddByte(part.Material); | ||
6250 | zc.AddByte(part.ClickAction); // clickaction | ||
6251 | zc.AddVector3(part.Shape.Scale); | ||
6252 | |||
6253 | // objectdata block | ||
6254 | zc.AddByte(60); // fixed object block size | ||
6255 | zc.AddVector3(part.RelativePosition); | ||
6256 | zc.AddVector3(part.Velocity); | ||
6257 | zc.AddVector3(part.Acceleration); | ||
6258 | Quaternion rotation = part.RotationOffset; | ||
6259 | rotation.Normalize(); | ||
6260 | zc.AddNormQuat(rotation); | ||
6261 | zc.AddVector3(part.AngularVelocity); | ||
6262 | |||
6263 | zc.AddUInt(part.ParentID); | ||
6264 | zc.AddUInt((uint)primflags); //update flags | ||
6265 | |||
6266 | //pbs | ||
6267 | zc.AddByte(part.Shape.PathCurve); | ||
6268 | zc.AddByte(profileCurve); | ||
6269 | zc.AddUInt16(part.Shape.PathBegin); | ||
6270 | zc.AddUInt16(part.Shape.PathEnd); | ||
6271 | zc.AddByte(part.Shape.PathScaleX); | ||
6272 | zc.AddByte(pathScaleY); | ||
6273 | zc.AddByte(part.Shape.PathShearX); | ||
6274 | zc.AddByte(part.Shape.PathShearY); | ||
6275 | zc.AddByte((byte)part.Shape.PathTwist); | ||
6276 | zc.AddByte((byte)part.Shape.PathTwistBegin); | ||
6277 | zc.AddByte((byte)part.Shape.PathRadiusOffset); | ||
6278 | zc.AddByte((byte)part.Shape.PathTaperX); | ||
6279 | zc.AddByte((byte)part.Shape.PathTaperY); | ||
6280 | zc.AddByte(part.Shape.PathRevolutions); | ||
6281 | zc.AddByte((byte)part.Shape.PathSkew); | ||
6282 | zc.AddUInt16(profileBegin); | ||
6283 | zc.AddUInt16(part.Shape.ProfileEnd); | ||
6284 | zc.AddUInt16(profileHollow); | ||
6285 | |||
6286 | // texture | ||
6287 | byte[] tentry = part.Shape.TextureEntry; | ||
6288 | if (tentry == null) | ||
6289 | zc.AddZeros(2); | ||
6290 | else | ||
6291 | { | ||
6292 | int len = tentry.Length; | ||
6293 | zc.AddUInt((ushort)len); | ||
6294 | zc.AddBytes(tentry, len); | ||
6295 | } | ||
6296 | |||
6297 | // texture animation | ||
6298 | byte[] tanim = part.TextureAnimation; | ||
6299 | if (tanim == null) | ||
6300 | zc.AddZeros(1); | ||
6301 | else | ||
6302 | { | ||
6303 | int len = tanim.Length; | ||
6304 | zc.AddByte((byte)len); | ||
6305 | zc.AddBytes(tanim, len); | ||
6306 | } | ||
6307 | |||
6308 | //NameValue | ||
6309 | if(nv == null) | ||
6310 | zc.AddZeros(2); | ||
6311 | else | ||
6312 | { | ||
6313 | int len = nv.Length; | ||
6314 | zc.AddByte((byte)len); | ||
6315 | zc.AddByte((byte)(len >> 8)); | ||
6316 | zc.AddBytes(nv, len); | ||
6317 | } | ||
6318 | |||
6319 | // data | ||
6320 | if (data == null) | ||
6321 | zc.AddZeros(2); | ||
6322 | else | ||
6323 | { | ||
6324 | int len = data.Length; | ||
6325 | zc.AddByte((byte)len); | ||
6326 | zc.AddByte((byte)(len >> 8)); | ||
6327 | zc.AddBytes(data, len); | ||
6328 | } | ||
6329 | |||
6330 | //text | ||
6331 | if (part.Text.Length == 0) | ||
6332 | zc.AddZeros(1); | ||
6333 | else | ||
6334 | { | ||
6335 | byte[] tbuf = Util.StringToBytes(part.Text, 255); | ||
6336 | int len = tbuf.Length; | ||
6337 | zc.AddByte((byte)len); | ||
6338 | zc.AddBytes(tbuf, len); | ||
6339 | } | ||
6340 | |||
6341 | //textcolor | ||
6342 | byte[] tc = part.GetTextColor().GetBytes(false); | ||
6343 | zc.AddBytes(tc, 4); | ||
6344 | |||
6345 | //media url | ||
6346 | if (part.MediaUrl.Length == 0) | ||
6347 | zc.AddZeros(1); | ||
6348 | else | ||
6349 | { | ||
6350 | byte[] tbuf = Util.StringToBytes(part.MediaUrl, 255); | ||
6351 | int len = tbuf.Length; | ||
6352 | zc.AddByte((byte)len); | ||
6353 | zc.AddBytes(tbuf, len); | ||
6354 | } | ||
6355 | |||
6356 | //particle system | ||
6357 | byte[] ps = part.ParticleSystem; | ||
6358 | if (ps == null) | ||
6359 | zc.AddZeros(1); | ||
6360 | else | ||
6361 | { | ||
6362 | int len = ps.Length; | ||
6363 | zc.AddByte((byte)len); | ||
6364 | zc.AddBytes(ps, len); | ||
6365 | } | ||
6366 | |||
6367 | //Extraparams | ||
6368 | byte[] ep = part.Shape.ExtraParams; | ||
6369 | if (ep == null) | ||
6370 | zc.AddZeros(1); | ||
6371 | else | ||
6372 | { | ||
6373 | int len = ep.Length; | ||
6374 | zc.AddByte((byte)len); | ||
6375 | zc.AddBytes(ep, len); | ||
6376 | } | ||
6377 | |||
6378 | zc.AddUUID(part.Sound); | ||
6379 | zc.AddUUID(part.OwnerID); | ||
6380 | zc.AddFloat((float)part.SoundGain); | ||
6381 | zc.AddByte(part.SoundFlags); | ||
6382 | zc.AddFloat((float)part.SoundRadius); | ||
6383 | |||
6384 | // jointtype(1) joint pivot(12) joint offset(12) | ||
6385 | const int lastzeros = 1 + 12 + 12; | ||
6386 | zc.AddZeros(lastzeros); | ||
6387 | } | ||
6388 | |||
6196 | protected ObjectUpdateCompressedPacket.ObjectDataBlock CreateCompressedUpdateBlock(SceneObjectPart part, PrimUpdateFlags updateFlags) | 6389 | protected ObjectUpdateCompressedPacket.ObjectDataBlock CreateCompressedUpdateBlock(SceneObjectPart part, PrimUpdateFlags updateFlags) |
6197 | { | 6390 | { |
6198 | // TODO: Implement this | 6391 | // TODO: Implement this |
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPZeroEncoder.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPZeroEncoder.cs index 4841ada..8ed2cf1 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPZeroEncoder.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPZeroEncoder.cs | |||
@@ -134,7 +134,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
134 | } | 134 | } |
135 | } | 135 | } |
136 | 136 | ||
137 | public void AddByte(byte v) | 137 | public unsafe void AddByte(byte v) |
138 | { | 138 | { |
139 | if (v == 0x00) | 139 | if (v == 0x00) |
140 | { | 140 | { |