aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorUbitUmarov2019-03-25 17:51:38 +0000
committerUbitUmarov2019-03-25 17:51:38 +0000
commit5035de053a533bb0407fb8ad11c44351026f6cf8 (patch)
tree6e60ca2c47e31e19e5868da0d2a88d5d92c55456
parentsome more changes on objects sending (diff)
downloadopensim-SC-5035de053a533bb0407fb8ad11c44351026f6cf8.zip
opensim-SC-5035de053a533bb0407fb8ad11c44351026f6cf8.tar.gz
opensim-SC-5035de053a533bb0407fb8ad11c44351026f6cf8.tar.bz2
opensim-SC-5035de053a533bb0407fb8ad11c44351026f6cf8.tar.xz
we should be able to zeroencode compressedupdates
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs456
1 files changed, 425 insertions, 31 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 601de61..187b6fa 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -4857,6 +4857,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4857 } 4857 }
4858 4858
4859 useCompressUpdate = false; 4859 useCompressUpdate = false;
4860 bool istree = false;
4860 4861
4861 if (update.Entity is SceneObjectPart) 4862 if (update.Entity is SceneObjectPart)
4862 { 4863 {
@@ -4973,8 +4974,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4973 maxUpdatesBytes -= 20 * part.Animations.Count + 24; 4974 maxUpdatesBytes -= 20 * part.Animations.Count + 24;
4974 } 4975 }
4975 } 4976 }
4977
4976 if(viewerCache) 4978 if(viewerCache)
4977 useCompressUpdate = grp.IsViewerCachable; 4979 useCompressUpdate = grp.IsViewerCachable;
4980
4981 istree = (part.Shape.PCode == (byte)PCode.Grass || part.Shape.PCode == (byte)PCode.NewTree || part.Shape.PCode == (byte)PCode.Tree);
4978 } 4982 }
4979 else if (update.Entity is ScenePresence) 4983 else if (update.Entity is ScenePresence)
4980 { 4984 {
@@ -5049,7 +5053,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5049 { 5053 {
5050 if (useCompressUpdate) 5054 if (useCompressUpdate)
5051 { 5055 {
5052 maxUpdatesBytes -= 150; // crude estimation 5056 if (istree)
5057 maxUpdatesBytes -= 64;
5058 else
5059 maxUpdatesBytes -= 100; // crude estimation
5053 5060
5054 if (compressedUpdates == null) 5061 if (compressedUpdates == null)
5055 { 5062 {
@@ -5060,7 +5067,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5060 } 5067 }
5061 else 5068 else
5062 { 5069 {
5063 maxUpdatesBytes -= 150; // crude estimation 5070 if (istree)
5071 maxUpdatesBytes -= 70;
5072 else
5073 maxUpdatesBytes -= 150; // crude estimation
5064 5074
5065 if (objectUpdates == null) 5075 if (objectUpdates == null)
5066 { 5076 {
@@ -5164,6 +5174,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5164 } 5174 }
5165 } 5175 }
5166 5176
5177 /* no zero encode compressed updates
5167 if(compressedUpdates != null) 5178 if(compressedUpdates != null)
5168 { 5179 {
5169 List<EntityUpdate> tau = new List<EntityUpdate>(30); 5180 List<EntityUpdate> tau = new List<EntityUpdate>(30);
@@ -5211,7 +5222,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5211 5222
5212 pos = 18; 5223 pos = 18;
5213 // im lazy now, just do last again 5224 // im lazy now, just do last again
5214 CreateCompressedUpdateBlock((SceneObjectPart)eu.Entity, mysp, data, ref pos); 5225 CreateCompressedUpdateBlock(sop, mysp, data, ref pos);
5215 tau = new List<EntityUpdate>(30); 5226 tau = new List<EntityUpdate>(30);
5216 tau.Add(eu); 5227 tau.Add(eu);
5217 count = 1; 5228 count = 1;
@@ -5226,6 +5237,88 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5226 delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false, false); 5237 delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false, false);
5227 } 5238 }
5228 } 5239 }
5240 */
5241
5242 if (compressedUpdates != null)
5243 {
5244 List<EntityUpdate> tau = new List<EntityUpdate>(30);
5245
5246 UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
5247 byte[] data = buf.Data;
5248
5249 Buffer.BlockCopy(CompressedObjectHeader, 0, data, 0, 7);
5250 data[0] |= Helpers.MSG_ZEROCODED;
5251
5252 LLUDPZeroEncoder zc = new LLUDPZeroEncoder(buf.Data);
5253 zc.Position = 7;
5254
5255 zc.AddUInt64(m_scene.RegionInfo.RegionHandle);
5256 zc.AddUInt16(timeDilation);
5257
5258 zc.AddByte(1); // tmp block count
5259
5260 int countposition = zc.Position - 1;
5261
5262 int lastpos = 0;
5263 int lastzc = 0;
5264
5265 int count = 0;
5266 foreach (EntityUpdate eu in compressedUpdates)
5267 {
5268 SceneObjectPart sop = (SceneObjectPart)eu.Entity;
5269 if (sop.ParentGroup == null || sop.ParentGroup.IsDeleted)
5270 continue;
5271 lastpos = zc.Position;
5272 lastzc = zc.ZeroCount;
5273
5274 CreateCompressedUpdateBlockZC(sop, mysp, zc);
5275 if (zc.Position < LLUDPServer.MAXPAYLOAD)
5276 {
5277 tau.Add(eu);
5278 ++count;
5279 }
5280 else
5281 {
5282 // we need more packets
5283 UDPPacketBuffer newbuf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
5284 Buffer.BlockCopy(buf.Data, 0, newbuf.Data, 0, countposition); // start is the same
5285
5286 buf.Data[countposition] = (byte)count;
5287 // get pending zeros at cut point
5288 if (lastzc > 0)
5289 {
5290 buf.Data[lastpos++] = 0;
5291 buf.Data[lastpos++] = (byte)lastzc;
5292 }
5293 buf.DataLength = lastpos;
5294
5295 m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task,
5296 delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false, false);
5297
5298 buf = newbuf;
5299 zc.Data = buf.Data;
5300
5301 data[0] |= Helpers.MSG_ZEROCODED;
5302
5303 zc.ZeroCount = 0;
5304 zc.Position = countposition + 1;
5305
5306 // im lazy now, just do last again
5307 CreateCompressedUpdateBlockZC(sop, mysp, zc);
5308 tau = new List<EntityUpdate>(30);
5309 tau.Add(eu);
5310 count = 1;
5311 }
5312 }
5313
5314 if (count > 0)
5315 {
5316 buf.Data[countposition] = (byte)count;
5317 buf.DataLength = zc.Finish();
5318 m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task,
5319 delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false, false);
5320 }
5321 }
5229 5322
5230 if (objectUpdateProbes != null) 5323 if (objectUpdateProbes != null)
5231 { 5324 {
@@ -7174,9 +7267,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7174 HasParticlesNew = 0x400 7267 HasParticlesNew = 0x400
7175 } 7268 }
7176 7269
7177 ///**** temp hack 7270 /*
7178 private static Random rnd = new Random();
7179
7180 protected void CreateCompressedUpdateBlock(SceneObjectPart part, ScenePresence sp, byte[] dest, ref int pos) 7271 protected void CreateCompressedUpdateBlock(SceneObjectPart part, ScenePresence sp, byte[] dest, ref int pos)
7181 { 7272 {
7182 // prepare data 7273 // prepare data
@@ -7197,13 +7288,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7197 } 7288 }
7198 } 7289 }
7199 7290
7200 // first is primFlags
7201 Utils.UIntToBytesSafepos((uint)primflags, dest, pos); pos += 4;
7202
7203 // datablock len to fill later
7204 int lenpos = pos;
7205 pos += 2;
7206
7207 byte state = part.Shape.State; 7291 byte state = part.Shape.State;
7208 PCode pcode = (PCode)part.Shape.PCode; 7292 PCode pcode = (PCode)part.Shape.PCode;
7209 7293
@@ -7278,12 +7362,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7278 pathScaleY = 150; 7362 pathScaleY = 150;
7279 } 7363 }
7280 7364
7365 // first is primFlags
7366 Utils.UIntToBytesSafepos((uint)primflags, dest, pos); pos += 4;
7367
7368 // datablock len to fill later
7369 int lenpos = pos;
7370 pos += 2;
7371
7372 // data block
7281 part.UUID.ToBytes(dest, pos); pos += 16; 7373 part.UUID.ToBytes(dest, pos); pos += 16;
7282 Utils.UIntToBytesSafepos(part.LocalId, dest, pos); pos += 4; 7374 Utils.UIntToBytesSafepos(part.LocalId, dest, pos); pos += 4;
7283 dest[pos++] = (byte)pcode; 7375 dest[pos++] = (byte)pcode;
7284 dest[pos++] = state; 7376 dest[pos++] = state;
7285 7377
7286 ///**** temp hack
7287 Utils.UIntToBytesSafepos((uint)part.ParentGroup.PseudoCRC, dest, pos); pos += 4; 7378 Utils.UIntToBytesSafepos((uint)part.ParentGroup.PseudoCRC, dest, pos); pos += 4;
7288 dest[pos++] = part.Material; 7379 dest[pos++] = part.Material;
7289 dest[pos++] = part.ClickAction; 7380 dest[pos++] = part.ClickAction;
@@ -7393,23 +7484,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7393 if (hastexanim) 7484 if (hastexanim)
7394 { 7485 {
7395 byte[] ta = part.TextureAnimation; 7486 byte[] ta = part.TextureAnimation;
7396 if (ta == null) 7487 int len = ta.Length & 0x7fff;
7397 { 7488 dest[pos++] = (byte)len;
7398 dest[pos++] = 0; 7489 dest[pos++] = (byte)(len >> 8);
7399 dest[pos++] = 0; 7490 dest[pos++] = 0;
7400 dest[pos++] = 0; 7491 dest[pos++] = 0;
7401 dest[pos++] = 0; 7492 Buffer.BlockCopy(ta, 0, dest, pos, len);
7402 } 7493 pos += len;
7403 else
7404 {
7405 int len = ta.Length & 0x7fff;
7406 dest[pos++] = (byte)len;
7407 dest[pos++] = (byte)(len >> 8);
7408 dest[pos++] = 0;
7409 dest[pos++] = 0;
7410 Buffer.BlockCopy(ta, 0, dest, pos, len);
7411 pos += len;
7412 }
7413 } 7494 }
7414 7495
7415 if (haspsnew) 7496 if (haspsnew)
@@ -7422,6 +7503,319 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7422 dest[lenpos++] = (byte)totlen; 7503 dest[lenpos++] = (byte)totlen;
7423 dest[lenpos++] = (byte)(totlen >> 8); 7504 dest[lenpos++] = (byte)(totlen >> 8);
7424 } 7505 }
7506 */
7507
7508 protected void CreateCompressedUpdateBlockZC(SceneObjectPart part, ScenePresence sp, LLUDPZeroEncoder zc)
7509 {
7510 // prepare data
7511 CompressedFlags cflags = CompressedFlags.None;
7512
7513 // prim/update flags
7514
7515 PrimFlags primflags = (PrimFlags)m_scene.Permissions.GenerateClientFlags(part, sp);
7516 // Don't send the CreateSelected flag to everyone
7517 primflags &= ~PrimFlags.CreateSelected;
7518 if (sp.UUID == part.OwnerID)
7519 {
7520 if (part.CreateSelected)
7521 {
7522 // Only send this flag once, then unset it
7523 primflags |= PrimFlags.CreateSelected;
7524 part.CreateSelected = false;
7525 }
7526 }
7527
7528 byte state = part.Shape.State;
7529 PCode pcode = (PCode)part.Shape.PCode;
7530
7531 // trees and grass are a lot more compact
7532 if (pcode == PCode.Grass || pcode == PCode.Tree || pcode == PCode.NewTree)
7533 {
7534 // first is primFlags
7535 zc.AddUInt((uint)primflags);
7536
7537 // datablock len
7538 zc.AddByte(113);
7539 zc.AddZeros(1);
7540
7541 // data block
7542 zc.AddUUID(part.UUID);
7543 zc.AddUInt(part.LocalId);
7544 zc.AddByte((byte)pcode);
7545 zc.AddByte(state);
7546
7547 zc.AddUInt((uint)part.ParentGroup.PseudoCRC);
7548
7549 zc.AddZeros(2); // material and click action
7550
7551 zc.AddVector3(part.Shape.Scale);
7552 zc.AddVector3(part.RelativePosition);
7553 if (pcode == PCode.Grass)
7554 zc.AddZeros(12);
7555 else
7556 {
7557 Quaternion rotation = part.RotationOffset;
7558 rotation.Normalize();
7559 zc.AddNormQuat(rotation);
7560 }
7561
7562 zc.AddUInt((uint)CompressedFlags.Tree); // cflags
7563
7564 zc.AddZeros(16); // owner id
7565
7566 zc.AddByte(state); // tree parameter
7567
7568 zc.AddZeros(28); //extraparameters 1, pbs 23, texture 4
7569
7570 return;
7571 }
7572
7573 //NameValue and state
7574 byte[] nv = null;
7575 if (part.ParentGroup.IsAttachment)
7576 {
7577 if (part.IsRoot)
7578 nv = Util.StringToBytes256("AttachItemID STRING RW SV " + part.ParentGroup.FromItemID);
7579
7580 int st = (int)part.ParentGroup.AttachmentPoint;
7581 state = (byte)(((st & 0xf0) >> 4) + ((st & 0x0f) << 4)); ;
7582 }
7583
7584 bool hastext = false;
7585 bool hassound = false;
7586 bool hasps = false;
7587 bool hastexanim = false;
7588 bool hasangvel = false;
7589 bool hasmediaurl = false;
7590 bool haspsnew = false;
7591
7592 int BlockLengh = 111;
7593
7594 byte[] extraParamBytes = part.Shape.ExtraParams;
7595 if (extraParamBytes == null || extraParamBytes.Length < 2)
7596 {
7597 ++BlockLengh;
7598 extraParamBytes = null;
7599 }
7600 else
7601 BlockLengh += extraParamBytes.Length;
7602
7603 byte[] hoverText = null;
7604 byte[] hoverTextColor = null;
7605 if (part.Text != null && part.Text.Length > 0)
7606 {
7607 cflags |= CompressedFlags.HasText;
7608 hoverText = Util.StringToBytes256(part.Text);
7609 BlockLengh += hoverText.Length;
7610 hoverTextColor = part.GetTextColor().GetBytes(false);
7611 BlockLengh += hoverTextColor.Length;
7612 hastext = true;
7613 }
7614
7615 if (part.ParticleSystem != null && part.ParticleSystem.Length > 1)
7616 {
7617 BlockLengh += part.ParticleSystem.Length;
7618 if (part.ParticleSystem.Length > 86)
7619 {
7620 hasps = false;
7621 cflags |= CompressedFlags.HasParticlesNew;
7622 haspsnew = true;
7623 }
7624 else
7625 {
7626 cflags |= CompressedFlags.HasParticlesLegacy;
7627 hasps = true;
7628 }
7629 }
7630
7631 if (part.Sound != UUID.Zero || part.SoundFlags != 0)
7632 {
7633 BlockLengh += 25;
7634 cflags |= CompressedFlags.HasSound;
7635 hassound = true;
7636 }
7637
7638 if (part.ParentID != 0)
7639 {
7640 BlockLengh += 4;
7641 cflags |= CompressedFlags.HasParent;
7642 }
7643
7644 if (part.TextureAnimation != null && part.TextureAnimation.Length > 0)
7645 {
7646 BlockLengh += part.TextureAnimation.Length + 4;
7647 cflags |= CompressedFlags.TextureAnimation;
7648 hastexanim = true;
7649 }
7650
7651 if (part.AngularVelocity.LengthSquared() > 1e-8f)
7652 {
7653 BlockLengh += 12;
7654 cflags |= CompressedFlags.HasAngularVelocity;
7655 hasangvel = true;
7656 }
7657
7658 byte[] mediaURLBytes = null;
7659 if (part.MediaUrl != null && part.MediaUrl.Length > 1)
7660 {
7661 mediaURLBytes = Util.StringToBytes256(part.MediaUrl); // must be null term
7662 BlockLengh += mediaURLBytes.Length;
7663 cflags |= CompressedFlags.MediaURL;
7664 hasmediaurl = true;
7665 }
7666
7667 if (nv != null)
7668 {
7669 BlockLengh += nv.Length;
7670 cflags |= CompressedFlags.HasNameValues;
7671 }
7672
7673 byte[] textureEntry = part.Shape.TextureEntry;
7674 if(textureEntry != null)
7675 BlockLengh += textureEntry.Length;
7676
7677 // filter out mesh faces hack
7678 ushort profileBegin = part.Shape.ProfileBegin;
7679 ushort profileHollow = part.Shape.ProfileHollow;
7680 byte profileCurve = part.Shape.ProfileCurve;
7681 byte pathScaleY = part.Shape.PathScaleY;
7682
7683 if (part.Shape.SculptType == (byte)SculptType.Mesh) // filter out hack
7684 {
7685 profileCurve = (byte)(part.Shape.ProfileCurve & 0x0f);
7686 // fix old values that confused viewers
7687 if (profileBegin == 1)
7688 profileBegin = 9375;
7689 if (profileHollow == 1)
7690 profileHollow = 27500;
7691 // fix torus hole size Y that also confuse some viewers
7692 if (profileCurve == (byte)ProfileShape.Circle && pathScaleY < 150)
7693 pathScaleY = 150;
7694 }
7695
7696
7697 // first is primFlags
7698 zc.AddUInt((uint)primflags);
7699
7700 // datablock len
7701 zc.AddByte((byte)BlockLengh);
7702 zc.AddByte((byte)(BlockLengh >> 8));
7703
7704 // data block
7705 zc.AddUUID(part.UUID);
7706 zc.AddUInt(part.LocalId);
7707 zc.AddByte((byte)pcode);
7708 zc.AddByte(state);
7709
7710 zc.AddUInt((uint)part.ParentGroup.PseudoCRC);
7711
7712 zc.AddByte(part.Material);
7713 zc.AddByte(part.ClickAction);
7714 zc.AddVector3(part.Shape.Scale);
7715 zc.AddVector3(part.RelativePosition);
7716 if (pcode == PCode.Grass)
7717 zc.AddZeros(12);
7718 else
7719 {
7720 Quaternion rotation = part.RotationOffset;
7721 rotation.Normalize();
7722 zc.AddNormQuat(rotation);
7723 }
7724
7725 zc.AddUInt((uint)cflags);
7726
7727 if (hasps || haspsnew || hassound)
7728 zc.AddUUID(part.OwnerID);
7729 else
7730 zc.AddZeros(16);
7731
7732 if (hasangvel)
7733 {
7734 zc.AddVector3(part.AngularVelocity);
7735 }
7736 if (part.ParentID != 0)
7737 {
7738 zc.AddUInt(part.ParentID);
7739 }
7740 if (hastext)
7741 {
7742 zc.AddBytes(hoverText, hoverText.Length);
7743 zc.AddBytes(hoverTextColor, hoverTextColor.Length);
7744 }
7745 if (hasmediaurl)
7746 {
7747 zc.AddBytes(mediaURLBytes, mediaURLBytes.Length);
7748 }
7749 if (hasps)
7750 {
7751 byte[] ps = part.ParticleSystem;
7752 zc.AddBytes(ps, ps.Length);
7753 }
7754 if (extraParamBytes == null)
7755 zc.AddZeros(1);
7756 else
7757 {
7758 zc.AddBytes(extraParamBytes, extraParamBytes.Length);
7759 }
7760 if (hassound)
7761 {
7762 zc.AddUUID(part.Sound);
7763 zc.AddFloat((float)part.SoundGain);
7764 zc.AddByte(part.SoundFlags);
7765 zc.AddFloat((float)part.SoundRadius);
7766 }
7767 if (nv != null)
7768 {
7769 zc.AddBytes(nv, nv.Length);
7770 }
7771
7772 zc.AddByte(part.Shape.PathCurve);
7773 zc.AddUInt16(part.Shape.PathBegin);
7774 zc.AddUInt16(part.Shape.PathEnd);
7775 zc.AddByte(part.Shape.PathScaleX);
7776 zc.AddByte(pathScaleY);
7777 zc.AddByte(part.Shape.PathShearX);
7778 zc.AddByte(part.Shape.PathShearY);
7779 zc.AddByte((byte)part.Shape.PathTwist);
7780 zc.AddByte((byte)part.Shape.PathTwistBegin);
7781 zc.AddByte((byte)part.Shape.PathRadiusOffset);
7782 zc.AddByte((byte)part.Shape.PathTaperX);
7783 zc.AddByte((byte)part.Shape.PathTaperY);
7784 zc.AddByte(part.Shape.PathRevolutions);
7785 zc.AddByte((byte)part.Shape.PathSkew);
7786 zc.AddByte(profileCurve);
7787 zc.AddUInt16(profileBegin);
7788 zc.AddUInt16(part.Shape.ProfileEnd);
7789 zc.AddUInt16(profileHollow);
7790
7791 if (textureEntry == null)
7792 {
7793 zc.AddZeros(4);
7794 }
7795 else
7796 {
7797 int len = textureEntry.Length;
7798 zc.AddByte((byte)len);
7799 zc.AddByte((byte)(len >> 8));
7800 zc.AddZeros(2);
7801 zc.AddBytes(textureEntry, len);
7802 }
7803 if (hastexanim)
7804 {
7805 byte[] ta = part.TextureAnimation;
7806 int len = ta.Length;
7807 zc.AddByte((byte)len);
7808 zc.AddByte((byte)(len >> 8));
7809 zc.AddZeros(2);
7810 zc.AddBytes(ta, len);
7811 }
7812
7813 if (haspsnew)
7814 {
7815 byte[] ps = part.ParticleSystem;
7816 zc.AddBytes(ps, ps.Length);
7817 }
7818 }
7425 7819
7426 public void SendNameReply(UUID profileId, string firstname, string lastname) 7820 public void SendNameReply(UUID profileId, string firstname, string lastname)
7427 { 7821 {