aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
diff options
context:
space:
mode:
authorUbitUmarov2019-03-14 17:11:23 +0000
committerUbitUmarov2019-03-14 17:11:23 +0000
commitf143dbc23fc5984728d32602f9602a4fcda35577 (patch)
treee93370398d31df5a33edbe4a2964f582893aa544 /OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
parentRobust: to tell main httpserver to stop on shutdown (diff)
downloadopensim-SC-f143dbc23fc5984728d32602f9602a4fcda35577.zip
opensim-SC-f143dbc23fc5984728d32602f9602a4fcda35577.tar.gz
opensim-SC-f143dbc23fc5984728d32602f9602a4fcda35577.tar.bz2
opensim-SC-f143dbc23fc5984728d32602f9602a4fcda35577.tar.xz
lludp direct encode object Properties update packets
Diffstat (limited to 'OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs327
1 files changed, 199 insertions, 128 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index ac041f5..181c4e2 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -5121,14 +5121,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5121 m_entityProps.Enqueue(priority, new ObjectPropertyUpdate(entity,0,false,true)); 5121 m_entityProps.Enqueue(priority, new ObjectPropertyUpdate(entity,0,false,true));
5122 } 5122 }
5123 5123
5124 static private readonly byte[] ObjectPropertyUpdateHeader = new byte[] {
5125 Helpers.MSG_RELIABLE | Helpers.MSG_ZEROCODED,
5126 0, 0, 0, 0, // sequence number
5127 0, // extra
5128 0xff, 9 // ID (medium frequency)
5129 };
5130
5131 static private readonly byte[] ObjectFamilyUpdateHeader = new byte[] {
5132 Helpers.MSG_RELIABLE | Helpers.MSG_ZEROCODED,
5133 0, 0, 0, 0, // sequence number
5134 0, // extra
5135 0xff, 10 // ID (medium frequency)
5136 };
5137
5124 private void ProcessEntityPropertyRequests(int maxUpdateBytes) 5138 private void ProcessEntityPropertyRequests(int maxUpdateBytes)
5125 { 5139 {
5126 List<ObjectPropertiesFamilyPacket.ObjectDataBlock> objectFamilyBlocks = null; 5140 List<ObjectPropertyUpdate> objectPropertiesUpdates = null;
5127 List<ObjectPropertiesPacket.ObjectDataBlock> objectPropertiesBlocks = null; 5141 List<ObjectPropertyUpdate> objectPropertiesFamilyUpdates = null;
5128 List<SceneObjectPart> needPhysics = null; 5142 List<SceneObjectPart> needPhysics = null;
5129 5143
5130 bool orderedDequeue = m_scene.UpdatePrioritizationScheme == UpdatePrioritizationSchemes.SimpleAngularDistance; 5144 // bool orderedDequeue = m_scene.UpdatePrioritizationScheme == UpdatePrioritizationSchemes.SimpleAngularDistance;
5131 5145 bool orderedDequeue = false; // for now
5132 EntityUpdate iupdate; 5146 EntityUpdate iupdate;
5133 5147
5134 while (maxUpdateBytes > 0) 5148 while (maxUpdateBytes > 0)
@@ -5153,11 +5167,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5153 if (update.Entity is SceneObjectPart) 5167 if (update.Entity is SceneObjectPart)
5154 { 5168 {
5155 SceneObjectPart sop = (SceneObjectPart)update.Entity; 5169 SceneObjectPart sop = (SceneObjectPart)update.Entity;
5156 ObjectPropertiesFamilyPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesFamilyBlock(sop,update.Flags); 5170 if(objectPropertiesFamilyUpdates == null)
5157 if(objectFamilyBlocks == null) 5171 objectPropertiesFamilyUpdates = new List<ObjectPropertyUpdate>();
5158 objectFamilyBlocks = new List<ObjectPropertiesFamilyPacket.ObjectDataBlock>(); 5172 objectPropertiesFamilyUpdates.Add(update);
5159 objectFamilyBlocks.Add(objPropDB); 5173 maxUpdateBytes -= 100;
5160 maxUpdateBytes -= objPropDB.Length;
5161 } 5174 }
5162 } 5175 }
5163 5176
@@ -5169,58 +5182,107 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5169 if(needPhysics == null) 5182 if(needPhysics == null)
5170 needPhysics = new List<SceneObjectPart>(); 5183 needPhysics = new List<SceneObjectPart>();
5171 needPhysics.Add(sop); 5184 needPhysics.Add(sop);
5172 ObjectPropertiesPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesBlock(sop); 5185 if(objectPropertiesUpdates == null)
5173 if(objectPropertiesBlocks == null) 5186 objectPropertiesUpdates = new List<ObjectPropertyUpdate>();
5174 objectPropertiesBlocks = new List<ObjectPropertiesPacket.ObjectDataBlock>(); 5187 objectPropertiesUpdates.Add(update);
5175 objectPropertiesBlocks.Add(objPropDB); 5188 maxUpdateBytes -= 200; // aprox
5176 maxUpdateBytes -= objPropDB.Length;
5177 } 5189 }
5178 } 5190 }
5179 } 5191 }
5180 5192
5181 if (objectPropertiesBlocks != null) 5193 if (objectPropertiesUpdates != null)
5182 { 5194 {
5183 ObjectPropertiesPacket packet = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); 5195 int blocks = objectPropertiesUpdates.Count;
5184 packet.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[objectPropertiesBlocks.Count]; 5196 //List<EntityUpdate> tau = new List<EntityUpdate>(30);
5185 for (int i = 0; i < objectPropertiesBlocks.Count; i++)
5186 packet.ObjectData[i] = objectPropertiesBlocks[i];
5187 5197
5188 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 5198 UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
5189 // of the object rather than the properties when the packet was created 5199 Buffer.BlockCopy(ObjectPropertyUpdateHeader, 0, buf.Data, 0, 8);
5190 // HACK : Remove intelligent resending until it's fixed in core 5200
5191 //OutPacket(packet, ThrottleOutPacketType.Task, true, 5201 LLUDPZeroEncoder zc = new LLUDPZeroEncoder(buf.Data);
5192 // delegate(OutgoingPacket oPacket) 5202 zc.Position = 8;
5193 // { 5203
5194 // ResendPropertyUpdates(propertyUpdates.Value, oPacket); 5204 zc.AddByte(1); // tmp block count
5195 // }); 5205
5196 OutPacket(packet, ThrottleOutPacketType.Task, true); 5206 int countposition = zc.Position - 1;
5207
5208 int lastpos = 0;
5209 int lastzc = 0;
5210
5211 int count = 0;
5212 foreach (EntityUpdate eu in objectPropertiesUpdates)
5213 {
5214 lastpos = zc.Position;
5215 lastzc = zc.ZeroCount;
5216 CreateObjectPropertiesBlock((SceneObjectPart)eu.Entity, zc);
5217 if (zc.Position < LLUDPServer.MAXPAYLOAD)
5218 {
5219 //tau.Add(eu);
5220 ++count;
5221 --blocks;
5222 }
5223 else if (blocks > 0)
5224 {
5225 // we need more packets
5226 UDPPacketBuffer newbuf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
5227 Buffer.BlockCopy(buf.Data, 0, newbuf.Data, 0, countposition); // start is the same
5228
5229 buf.Data[countposition] = (byte)count;
5230 // get pending zeros at cut point
5231 if (lastzc > 0)
5232 {
5233 buf.Data[lastpos++] = 0;
5234 buf.Data[lastpos++] = (byte)lastzc;
5235 }
5236 buf.DataLength = lastpos;
5237
5238 //m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task,
5239 // delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false, false);
5240 m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task, null, false, false);
5241 buf = newbuf;
5242 zc.Data = buf.Data;
5243 zc.ZeroCount = 0;
5244 zc.Position = countposition + 1;
5245 // im lazy now, just do last again
5246 CreateObjectPropertiesBlock((SceneObjectPart)eu.Entity, zc);
5247
5248 //tau = new List<EntityUpdate>(30);
5249 //tau.Add(eu);
5250 count = 1;
5251 --blocks;
5252 }
5253 }
5254
5255 if (count > 0)
5256 {
5257 buf.Data[countposition] = (byte)count;
5258 buf.DataLength = zc.Finish();
5259 //m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task,
5260 // delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false, false);
5261 m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task, null, false, false);
5262 }
5197 } 5263 }
5198 5264
5199 if (objectFamilyBlocks != null) 5265 if (objectPropertiesFamilyUpdates != null)
5200 { 5266 {
5201 // one packet per object block... uggh... 5267 foreach (EntityUpdate eu in objectPropertiesFamilyUpdates)
5202 for (int i = 0; i < objectFamilyBlocks.Count; i++)
5203 { 5268 {
5204 ObjectPropertiesFamilyPacket packet = 5269 UDPPacketBuffer buf = m_udpServer.GetNewUDPBuffer(m_udpClient.RemoteEndPoint);
5205 (ObjectPropertiesFamilyPacket)PacketPool.Instance.GetPacket(PacketType.ObjectPropertiesFamily); 5270 Buffer.BlockCopy(ObjectFamilyUpdateHeader, 0, buf.Data, 0, 8);
5206 5271
5207 packet.ObjectData = objectFamilyBlocks[i]; 5272 LLUDPZeroEncoder zc = new LLUDPZeroEncoder(buf.Data);
5273 zc.Position = 8;
5208 5274
5209 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 5275 CreateObjectPropertiesFamilyBlock((SceneObjectPart)eu.Entity, eu.Flags, zc);
5210 // of the object rather than the properties when the packet was created 5276 buf.DataLength = zc.Finish();
5211// List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 5277 //List<EntityUpdate> tau = new List<EntityUpdate>(1);
5212// updates.Add(familyUpdates.Value[i]); 5278 //tau.Add(new ObjectPropertyUpdate((ISceneEntity) eu, (uint)eu.Flags, true, false));
5213 // HACK : Remove intelligent resending until it's fixed in core 5279 //m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task,
5214 //OutPacket(packet, ThrottleOutPacketType.Task, true, 5280 // delegate (OutgoingPacket oPacket) { ResendPrimUpdates(tau, oPacket); }, false, false);
5215 // delegate(OutgoingPacket oPacket) 5281 m_udpServer.SendUDPPacket(m_udpClient, buf, ThrottleOutPacketType.Task, null, false, false);
5216 // {
5217 // ResendPropertyUpdates(updates, oPacket);
5218 // });
5219 OutPacket(packet, ThrottleOutPacketType.Task, true);
5220 } 5282 }
5221 } 5283 }
5222 5284
5223 if(needPhysics != null) 5285 if (needPhysics != null)
5224 { 5286 {
5225 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>(); 5287 IEventQueue eq = Scene.RequestModuleInterface<IEventQueue>();
5226 if(eq != null) 5288 if(eq != null)
@@ -5245,101 +5307,110 @@ namespace OpenSim.Region.ClientStack.LindenUDP
5245 } 5307 }
5246 } 5308 }
5247 5309
5248 private ObjectPropertiesFamilyPacket.ObjectDataBlock CreateObjectPropertiesFamilyBlock(SceneObjectPart sop, PrimUpdateFlags requestFlags) 5310 private void CreateObjectPropertiesFamilyBlock(SceneObjectPart sop, PrimUpdateFlags requestFlags, LLUDPZeroEncoder zc)
5249 { 5311 {
5250 ObjectPropertiesFamilyPacket.ObjectDataBlock block = new ObjectPropertiesFamilyPacket.ObjectDataBlock(); 5312 SceneObjectPart root = sop.ParentGroup.RootPart;
5251 5313
5252 block.RequestFlags = (uint)requestFlags; 5314 zc.AddUInt((uint)requestFlags);
5253 block.ObjectID = sop.UUID; 5315 zc.AddUUID(sop.UUID);
5254 if (sop.OwnerID == sop.GroupID) 5316 if (sop.OwnerID == sop.GroupID)
5255 block.OwnerID = UUID.Zero; 5317 zc.AddZeros(16);
5256 else 5318 else
5257 block.OwnerID = sop.OwnerID; 5319 zc.AddUUID(sop.OwnerID);
5258 block.GroupID = sop.GroupID; 5320 zc.AddUUID(sop.GroupID);
5259 block.BaseMask = sop.BaseMask;
5260 block.OwnerMask = sop.OwnerMask;
5261 block.GroupMask = sop.GroupMask;
5262 block.EveryoneMask = sop.EveryoneMask;
5263 block.NextOwnerMask = sop.NextOwnerMask;
5264
5265 // TODO: More properties are needed in SceneObjectPart!
5266 block.OwnershipCost = sop.OwnershipCost;
5267 block.SaleType = sop.ObjectSaleType;
5268 block.SalePrice = sop.SalePrice;
5269 block.Category = sop.Category;
5270 block.LastOwnerID = sop.LastOwnerID;
5271 block.Name = Util.StringToBytes256(sop.Name);
5272 block.Description = Util.StringToBytes256(sop.Description);
5273 5321
5274 return block; 5322 zc.AddUInt(root.BaseMask);
5275 } 5323 zc.AddUInt(root.OwnerMask);
5324 zc.AddUInt(root.GroupMask);
5325 zc.AddUInt(root.EveryoneMask);
5326 zc.AddUInt(root.NextOwnerMask);
5276 5327
5277 private ObjectPropertiesPacket.ObjectDataBlock CreateObjectPropertiesBlock(SceneObjectPart sop) 5328 zc.AddZeros(4); // int ownership cost
5278 {
5279 //ObjectPropertiesPacket proper = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties);
5280 // TODO: don't create new blocks if recycling an old packet
5281 5329
5282 ObjectPropertiesPacket.ObjectDataBlock block = 5330 //sale info block
5283 new ObjectPropertiesPacket.ObjectDataBlock(); 5331 zc.AddByte(root.ObjectSaleType);
5332 zc.AddInt(root.SalePrice);
5284 5333
5285 block.ObjectID = sop.UUID; 5334 zc.AddUInt(sop.Category); //Category
5286 block.Name = Util.StringToBytes256(sop.Name);
5287 block.Description = Util.StringToBytes256(sop.Description);
5288 5335
5289 block.CreationDate = (ulong)sop.CreationDate * 1000000; // viewer wants date in microseconds 5336 zc.AddUUID(sop.LastOwnerID);
5290 block.CreatorID = sop.CreatorID;
5291 block.GroupID = sop.GroupID;
5292 block.LastOwnerID = sop.LastOwnerID;
5293 if (sop.OwnerID == sop.GroupID)
5294 block.OwnerID = UUID.Zero;
5295 else
5296 block.OwnerID = sop.OwnerID;
5297 5337
5298 block.ItemID = sop.FromUserInventoryItemID; 5338 //name
5299 block.FolderID = UUID.Zero; // sog.FromFolderID ?? 5339 byte[] tmpbytes = Util.StringToBytes256(sop.Name);
5300 block.FromTaskID = UUID.Zero; // ??? 5340 zc.AddByte((byte)tmpbytes.Length);
5301 block.InventorySerial = (short)sop.InventorySerial; 5341 zc.AddBytes(tmpbytes, tmpbytes.Length);
5302 5342
5303 SceneObjectPart root = sop.ParentGroup.RootPart; 5343 //Description
5304 5344 tmpbytes = Util.StringToBytes256(sop.Description);
5305 block.TouchName = Util.StringToBytes256(root.TouchName); 5345 zc.AddByte((byte)tmpbytes.Length);
5346 zc.AddBytes(tmpbytes, tmpbytes.Length);
5347 }
5306 5348
5307 // SL 3.3.4, at least, appears to read this information as a concatenated byte[] stream of UUIDs but 5349 private void CreateObjectPropertiesBlock(SceneObjectPart sop, LLUDPZeroEncoder zc)
5308 // it's not yet clear whether this is actually used. If this is done in the future then a pre-cached 5350 {
5309 // copy is really needed since it's less efficient to be constantly recreating this byte array. 5351 SceneObjectPart root = sop.ParentGroup.RootPart;
5310// using (MemoryStream memStream = new MemoryStream())
5311// {
5312// using (BinaryWriter binWriter = new BinaryWriter(memStream))
5313// {
5314// for (int i = 0; i < sop.GetNumberOfSides(); i++)
5315// {
5316// Primitive.TextureEntryFace teFace = sop.Shape.Textures.FaceTextures[i];
5317//
5318// UUID textureID;
5319//
5320// if (teFace != null)
5321// textureID = teFace.TextureID;
5322// else
5323// textureID = sop.Shape.Textures.DefaultTexture.TextureID;
5324//
5325// binWriter.Write(textureID.GetBytes());
5326// }
5327//
5328// block.TextureID = memStream.ToArray();
5329// }
5330// }
5331
5332 block.TextureID = new byte[0]; // TextureID ???
5333 block.SitName = Util.StringToBytes256(root.SitName);
5334 block.OwnerMask = root.OwnerMask;
5335 block.NextOwnerMask = root.NextOwnerMask;
5336 block.GroupMask = root.GroupMask;
5337 block.EveryoneMask = root.EveryoneMask;
5338 block.BaseMask = root.BaseMask;
5339 block.SaleType = root.ObjectSaleType;
5340 block.SalePrice = root.SalePrice;
5341 5352
5342 return block; 5353 zc.AddUUID(sop.UUID);
5354 zc.AddUUID(sop.CreatorID);
5355 if (sop.OwnerID == sop.GroupID)
5356 zc.AddZeros(16);
5357 else
5358 zc.AddUUID(sop.OwnerID);
5359 zc.AddUUID(sop.GroupID);
5360
5361 zc.AddUInt64((ulong)sop.CreationDate * 1000000UL);
5362
5363 zc.AddUInt(root.BaseMask);
5364 zc.AddUInt(root.OwnerMask);
5365 zc.AddUInt(root.GroupMask);
5366 zc.AddUInt(root.EveryoneMask);
5367 zc.AddUInt(root.NextOwnerMask);
5368
5369 zc.AddZeros(4); // int ownership cost
5370
5371 //sale info block
5372 zc.AddByte(root.ObjectSaleType);
5373 zc.AddInt(root.SalePrice);
5374
5375 //aggregated perms we may will need to fix this
5376 zc.AddByte(0); //AggregatePerms
5377 zc.AddByte(0); //AggregatePermTextures;
5378 zc.AddByte(0); //AggregatePermTexturesOwner
5379
5380 //inventory info
5381 zc.AddUInt(sop.Category); //Category
5382 zc.AddInt16((short)sop.InventorySerial);
5383 zc.AddUUID(sop.FromUserInventoryItemID);
5384 zc.AddUUID(UUID.Zero); //FolderID
5385 zc.AddUUID(UUID.Zero); //FromTaskID
5386
5387 zc.AddUUID(sop.LastOwnerID);
5388
5389 //name
5390 byte[] tmpbytes = Util.StringToBytes256(sop.Name);
5391 zc.AddByte((byte)tmpbytes.Length);
5392 zc.AddBytes(tmpbytes, tmpbytes.Length);
5393
5394 //Description
5395 tmpbytes = Util.StringToBytes256(sop.Description);
5396 zc.AddByte((byte)tmpbytes.Length);
5397 zc.AddBytes(tmpbytes, tmpbytes.Length);
5398
5399 // touch name
5400 tmpbytes = Util.StringToBytes256(root.TouchName);
5401 zc.AddByte((byte)tmpbytes.Length);
5402 zc.AddBytes(tmpbytes, tmpbytes.Length);
5403
5404 // sit name
5405 tmpbytes = Util.StringToBytes256(root.SitName);
5406 zc.AddByte((byte)tmpbytes.Length);
5407 zc.AddBytes(tmpbytes, tmpbytes.Length);
5408
5409 //texture ids block
5410 // still not sending, not clear the impact on viewers, if any.
5411 // does seem redundant
5412 // to send we will need proper list of face texture ids without having to unpack texture entry all the time
5413 zc.AddZeros(1);
5343 } 5414 }
5344 5415
5345 #region Estate Data Sending Methods 5416 #region Estate Data Sending Methods