diff options
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs')
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 137 |
1 files changed, 114 insertions, 23 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 803114f..cd438d6 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | |||
@@ -3596,6 +3596,40 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3596 | m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation)); | 3596 | m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation)); |
3597 | } | 3597 | } |
3598 | 3598 | ||
3599 | /// <summary> | ||
3600 | /// Requeue an EntityUpdate when it was not acknowledged by the client. | ||
3601 | /// We will update the priority and put it in the correct queue, merging update flags | ||
3602 | /// with any other updates that may be queued for the same entity. | ||
3603 | /// The original update time is used for the merged update. | ||
3604 | /// </summary> | ||
3605 | private void ResendPrimUpdate(EntityUpdate update) | ||
3606 | { | ||
3607 | // If the update exists in priority queue, it will be updated. | ||
3608 | // If it does not exist then it will be added with the current (rather than its original) priority | ||
3609 | uint priority = m_prioritizer.GetUpdatePriority(this, update.Entity); | ||
3610 | |||
3611 | lock (m_entityUpdates.SyncRoot) | ||
3612 | m_entityUpdates.Enqueue(priority, update); | ||
3613 | } | ||
3614 | |||
3615 | /// <summary> | ||
3616 | /// Requeue a list of EntityUpdates when they were not acknowledged by the client. | ||
3617 | /// We will update the priority and put it in the correct queue, merging update flags | ||
3618 | /// with any other updates that may be queued for the same entity. | ||
3619 | /// The original update time is used for the merged update. | ||
3620 | /// </summary> | ||
3621 | private void ResendPrimUpdates(List<EntityUpdate> updates, OutgoingPacket oPacket) | ||
3622 | { | ||
3623 | // m_log.WarnFormat("[CLIENT] resending prim update {0}",updates[0].UpdateTime); | ||
3624 | |||
3625 | // Remove the update packet from the list of packets waiting for acknowledgement | ||
3626 | // because we are requeuing the list of updates. They will be resent in new packets | ||
3627 | // with the most recent state and priority. | ||
3628 | m_udpClient.NeedAcks.Remove(oPacket.SequenceNumber, 0, true); | ||
3629 | foreach (EntityUpdate update in updates) | ||
3630 | ResendPrimUpdate(update); | ||
3631 | } | ||
3632 | |||
3599 | private void ProcessEntityUpdates(int maxUpdates) | 3633 | private void ProcessEntityUpdates(int maxUpdates) |
3600 | { | 3634 | { |
3601 | OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>(); | 3635 | OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>(); |
@@ -3603,6 +3637,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3603 | OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>(); | 3637 | OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>(); |
3604 | OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseAgentUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>(); | 3638 | OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseAgentUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>(); |
3605 | 3639 | ||
3640 | OpenSim.Framework.Lazy<List<EntityUpdate>> objectUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); | ||
3641 | OpenSim.Framework.Lazy<List<EntityUpdate>> compressedUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); | ||
3642 | OpenSim.Framework.Lazy<List<EntityUpdate>> terseUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); | ||
3643 | OpenSim.Framework.Lazy<List<EntityUpdate>> terseAgentUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); | ||
3644 | |||
3606 | // Check to see if this is a flush | 3645 | // Check to see if this is a flush |
3607 | if (maxUpdates <= 0) | 3646 | if (maxUpdates <= 0) |
3608 | { | 3647 | { |
@@ -4027,7 +4066,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4027 | { | 4066 | { |
4028 | SendFamilyProps = SendFamilyProps || update.SendFamilyProps; | 4067 | SendFamilyProps = SendFamilyProps || update.SendFamilyProps; |
4029 | SendObjectProps = SendObjectProps || update.SendObjectProps; | 4068 | SendObjectProps = SendObjectProps || update.SendObjectProps; |
4030 | Flags |= update.Flags; | 4069 | // other properties may need to be updated by base class |
4070 | base.Update(update); | ||
4031 | } | 4071 | } |
4032 | } | 4072 | } |
4033 | 4073 | ||
@@ -4038,6 +4078,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4038 | m_entityProps.Enqueue(priority, new ObjectPropertyUpdate(entity,requestFlags,true,false)); | 4078 | m_entityProps.Enqueue(priority, new ObjectPropertyUpdate(entity,requestFlags,true,false)); |
4039 | } | 4079 | } |
4040 | 4080 | ||
4081 | private void ResendPropertyUpdate(ObjectPropertyUpdate update) | ||
4082 | { | ||
4083 | uint priority = 0; | ||
4084 | lock (m_entityProps.SyncRoot) | ||
4085 | m_entityProps.Enqueue(priority, update); | ||
4086 | } | ||
4087 | |||
4088 | private void ResendPropertyUpdates(List<ObjectPropertyUpdate> updates, OutgoingPacket oPacket) | ||
4089 | { | ||
4090 | // m_log.WarnFormat("[CLIENT] resending object property {0}",updates[0].UpdateTime); | ||
4091 | |||
4092 | // Remove the update packet from the list of packets waiting for acknowledgement | ||
4093 | // because we are requeuing the list of updates. They will be resent in new packets | ||
4094 | // with the most recent state. | ||
4095 | m_udpClient.NeedAcks.Remove(oPacket.SequenceNumber, 0, true); | ||
4096 | foreach (ObjectPropertyUpdate update in updates) | ||
4097 | ResendPropertyUpdate(update); | ||
4098 | } | ||
4099 | |||
4041 | public void SendObjectPropertiesReply(ISceneEntity entity) | 4100 | public void SendObjectPropertiesReply(ISceneEntity entity) |
4042 | { | 4101 | { |
4043 | uint priority = 0; // time based ordering only | 4102 | uint priority = 0; // time based ordering only |
@@ -4053,6 +4112,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4053 | OpenSim.Framework.Lazy<List<ObjectPropertiesPacket.ObjectDataBlock>> objectPropertiesBlocks = | 4112 | OpenSim.Framework.Lazy<List<ObjectPropertiesPacket.ObjectDataBlock>> objectPropertiesBlocks = |
4054 | new OpenSim.Framework.Lazy<List<ObjectPropertiesPacket.ObjectDataBlock>>(); | 4113 | new OpenSim.Framework.Lazy<List<ObjectPropertiesPacket.ObjectDataBlock>>(); |
4055 | 4114 | ||
4115 | OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>> familyUpdates = | ||
4116 | new OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>>(); | ||
4117 | |||
4118 | OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>> propertyUpdates = | ||
4119 | new OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>>(); | ||
4120 | |||
4056 | IEntityUpdate iupdate; | 4121 | IEntityUpdate iupdate; |
4057 | Int32 timeinqueue; // this is just debugging code & can be dropped later | 4122 | Int32 timeinqueue; // this is just debugging code & can be dropped later |
4058 | 4123 | ||
@@ -4071,6 +4136,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4071 | SceneObjectPart sop = (SceneObjectPart)update.Entity; | 4136 | SceneObjectPart sop = (SceneObjectPart)update.Entity; |
4072 | ObjectPropertiesFamilyPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesFamilyBlock(sop,update.Flags); | 4137 | ObjectPropertiesFamilyPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesFamilyBlock(sop,update.Flags); |
4073 | objectFamilyBlocks.Value.Add(objPropDB); | 4138 | objectFamilyBlocks.Value.Add(objPropDB); |
4139 | familyUpdates.Value.Add(update); | ||
4074 | } | 4140 | } |
4075 | } | 4141 | } |
4076 | 4142 | ||
@@ -4081,6 +4147,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4081 | SceneObjectPart sop = (SceneObjectPart)update.Entity; | 4147 | SceneObjectPart sop = (SceneObjectPart)update.Entity; |
4082 | ObjectPropertiesPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesBlock(sop); | 4148 | ObjectPropertiesPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesBlock(sop); |
4083 | objectPropertiesBlocks.Value.Add(objPropDB); | 4149 | objectPropertiesBlocks.Value.Add(objPropDB); |
4150 | propertyUpdates.Value.Add(update); | ||
4084 | } | 4151 | } |
4085 | } | 4152 | } |
4086 | 4153 | ||
@@ -4088,12 +4155,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4088 | } | 4155 | } |
4089 | 4156 | ||
4090 | 4157 | ||
4091 | Int32 ppcnt = 0; | 4158 | // Int32 ppcnt = 0; |
4092 | Int32 pbcnt = 0; | 4159 | // Int32 pbcnt = 0; |
4093 | 4160 | ||
4094 | if (objectPropertiesBlocks.IsValueCreated) | 4161 | if (objectPropertiesBlocks.IsValueCreated) |
4095 | { | 4162 | { |
4096 | List<ObjectPropertiesPacket.ObjectDataBlock> blocks = objectPropertiesBlocks.Value; | 4163 | List<ObjectPropertiesPacket.ObjectDataBlock> blocks = objectPropertiesBlocks.Value; |
4164 | List<ObjectPropertyUpdate> updates = propertyUpdates.Value; | ||
4097 | 4165 | ||
4098 | ObjectPropertiesPacket packet = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); | 4166 | ObjectPropertiesPacket packet = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); |
4099 | packet.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[blocks.Count]; | 4167 | packet.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[blocks.Count]; |
@@ -4101,28 +4169,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4101 | packet.ObjectData[i] = blocks[i]; | 4169 | packet.ObjectData[i] = blocks[i]; |
4102 | 4170 | ||
4103 | packet.Header.Zerocoded = true; | 4171 | packet.Header.Zerocoded = true; |
4104 | OutPacket(packet, ThrottleOutPacketType.Task, true); | ||
4105 | 4172 | ||
4106 | pbcnt += blocks.Count; | 4173 | // Pass in the delegate so that if this packet needs to be resent, we send the current properties |
4107 | ppcnt++; | 4174 | // of the object rather than the properties when the packet was created |
4175 | OutPacket(packet, ThrottleOutPacketType.Task, true, | ||
4176 | delegate(OutgoingPacket oPacket) | ||
4177 | { | ||
4178 | ResendPropertyUpdates(updates, oPacket); | ||
4179 | }); | ||
4180 | |||
4181 | // pbcnt += blocks.Count; | ||
4182 | // ppcnt++; | ||
4108 | } | 4183 | } |
4109 | 4184 | ||
4110 | Int32 fpcnt = 0; | 4185 | // Int32 fpcnt = 0; |
4111 | Int32 fbcnt = 0; | 4186 | // Int32 fbcnt = 0; |
4112 | 4187 | ||
4113 | if (objectFamilyBlocks.IsValueCreated) | 4188 | if (objectFamilyBlocks.IsValueCreated) |
4114 | { | 4189 | { |
4115 | List<ObjectPropertiesFamilyPacket.ObjectDataBlock> blocks = objectFamilyBlocks.Value; | 4190 | List<ObjectPropertiesFamilyPacket.ObjectDataBlock> blocks = objectFamilyBlocks.Value; |
4116 | 4191 | ||
4117 | // ObjectPropertiesFamilyPacket objPropFamilyPack = | ||
4118 | // (ObjectPropertiesFamilyPacket)PacketPool.Instance.GetPacket(PacketType.ObjectPropertiesFamily); | ||
4119 | // | ||
4120 | // objPropFamilyPack.ObjectData = new ObjectPropertiesFamilyPacket.ObjectDataBlock[blocks.Count]; | ||
4121 | // for (int i = 0; i < blocks.Count; i++) | ||
4122 | // objPropFamilyPack.ObjectData[i] = blocks[i]; | ||
4123 | // | ||
4124 | // OutPacket(objPropFamilyPack, ThrottleOutPacketType.Task, true); | ||
4125 | |||
4126 | // one packet per object block... uggh... | 4192 | // one packet per object block... uggh... |
4127 | for (int i = 0; i < blocks.Count; i++) | 4193 | for (int i = 0; i < blocks.Count; i++) |
4128 | { | 4194 | { |
@@ -4131,10 +4197,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4131 | 4197 | ||
4132 | packet.ObjectData = blocks[i]; | 4198 | packet.ObjectData = blocks[i]; |
4133 | packet.Header.Zerocoded = true; | 4199 | packet.Header.Zerocoded = true; |
4134 | OutPacket(packet, ThrottleOutPacketType.Task); | ||
4135 | 4200 | ||
4136 | fpcnt++; | 4201 | // Pass in the delegate so that if this packet needs to be resent, we send the current properties |
4137 | fbcnt++; | 4202 | // of the object rather than the properties when the packet was created |
4203 | List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); | ||
4204 | updates.Add(familyUpdates.Value[i]); | ||
4205 | OutPacket(packet, ThrottleOutPacketType.Task, true, | ||
4206 | delegate(OutgoingPacket oPacket) | ||
4207 | { | ||
4208 | ResendPropertyUpdates(updates, oPacket); | ||
4209 | }); | ||
4210 | |||
4211 | // fpcnt++; | ||
4212 | // fbcnt++; | ||
4138 | } | 4213 | } |
4139 | 4214 | ||
4140 | } | 4215 | } |
@@ -4171,7 +4246,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4171 | 4246 | ||
4172 | return block; | 4247 | return block; |
4173 | } | 4248 | } |
4174 | 4249 | ||
4175 | private ObjectPropertiesPacket.ObjectDataBlock CreateObjectPropertiesBlock(SceneObjectPart sop) | 4250 | private ObjectPropertiesPacket.ObjectDataBlock CreateObjectPropertiesBlock(SceneObjectPart sop) |
4176 | { | 4251 | { |
4177 | //ObjectPropertiesPacket proper = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); | 4252 | //ObjectPropertiesPacket proper = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); |
@@ -11473,6 +11548,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
11473 | /// handles splitting manually</param> | 11548 | /// handles splitting manually</param> |
11474 | protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting) | 11549 | protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting) |
11475 | { | 11550 | { |
11551 | OutPacket(packet, throttlePacketType, doAutomaticSplitting, null); | ||
11552 | } | ||
11553 | |||
11554 | /// <summary> | ||
11555 | /// This is the starting point for sending a simulator packet out to the client | ||
11556 | /// </summary> | ||
11557 | /// <param name="packet">Packet to send</param> | ||
11558 | /// <param name="throttlePacketType">Throttling category for the packet</param> | ||
11559 | /// <param name="doAutomaticSplitting">True to automatically split oversized | ||
11560 | /// packets (the default), or false to disable splitting if the calling code | ||
11561 | /// handles splitting manually</param> | ||
11562 | /// <param name="method">The method to be called in the event this packet is reliable | ||
11563 | /// and unacknowledged. The server will provide normal resend capability if you do not | ||
11564 | /// provide your own method.</param> | ||
11565 | protected void OutPacket(Packet packet, ThrottleOutPacketType throttlePacketType, bool doAutomaticSplitting, UnackedPacketMethod method) | ||
11566 | { | ||
11476 | if (m_debugPacketLevel > 0) | 11567 | if (m_debugPacketLevel > 0) |
11477 | { | 11568 | { |
11478 | bool logPacket = true; | 11569 | bool logPacket = true; |
@@ -11498,7 +11589,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
11498 | m_log.DebugFormat("[CLIENT]: Packet OUT {0}", packet.Type); | 11589 | m_log.DebugFormat("[CLIENT]: Packet OUT {0}", packet.Type); |
11499 | } | 11590 | } |
11500 | 11591 | ||
11501 | m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting); | 11592 | m_udpServer.SendPacket(m_udpClient, packet, throttlePacketType, doAutomaticSplitting, method); |
11502 | } | 11593 | } |
11503 | 11594 | ||
11504 | public bool AddMoney(int debit) | 11595 | public bool AddMoney(int debit) |