diff options
Diffstat (limited to 'OpenSim/Region/ClientStack')
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 115 | ||||
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLPacketTracker.cs | 234 |
2 files changed, 309 insertions, 40 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 2c05097..c9fc83a 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | |||
@@ -118,6 +118,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
118 | 118 | ||
119 | private Dictionary<string, LLUUID> m_defaultAnimations = new Dictionary<string, LLUUID>(); | 119 | private Dictionary<string, LLUUID> m_defaultAnimations = new Dictionary<string, LLUUID>(); |
120 | 120 | ||
121 | private LLPacketTracker m_packetTracker; | ||
122 | |||
121 | /* protected variables */ | 123 | /* protected variables */ |
122 | 124 | ||
123 | protected static Dictionary<PacketType, PacketMethod> PacketHandlers = | 125 | protected static Dictionary<PacketType, PacketMethod> PacketHandlers = |
@@ -282,6 +284,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
282 | private SetScriptRunning handlerSetScriptRunning = null; | 284 | private SetScriptRunning handlerSetScriptRunning = null; |
283 | private UpdateVector handlerAutoPilotGo = null; | 285 | private UpdateVector handlerAutoPilotGo = null; |
284 | 286 | ||
287 | private TerrainUnacked handlerUnackedTerrain = null; | ||
288 | |||
289 | //** | ||
290 | |||
285 | /* Properties */ | 291 | /* Properties */ |
286 | 292 | ||
287 | public LLUUID SecureSessionId | 293 | public LLUUID SecureSessionId |
@@ -377,6 +383,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
377 | public LLClientView(EndPoint remoteEP, IScene scene, AssetCache assetCache, LLPacketServer packServer, | 383 | public LLClientView(EndPoint remoteEP, IScene scene, AssetCache assetCache, LLPacketServer packServer, |
378 | AgentCircuitManager authenSessions, LLUUID agentId, LLUUID sessionId, uint circuitCode, EndPoint proxyEP) | 384 | AgentCircuitManager authenSessions, LLUUID agentId, LLUUID sessionId, uint circuitCode, EndPoint proxyEP) |
379 | { | 385 | { |
386 | m_packetTracker = new LLPacketTracker(this); | ||
387 | |||
380 | m_moneyBalance = 1000; | 388 | m_moneyBalance = 1000; |
381 | 389 | ||
382 | m_channelVersion = Helpers.StringToField(scene.GetSimulatorVersion()); | 390 | m_channelVersion = Helpers.StringToField(scene.GetSimulatorVersion()); |
@@ -410,6 +418,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
410 | 418 | ||
411 | RegisterLocalPacketHandlers(); | 419 | RegisterLocalPacketHandlers(); |
412 | 420 | ||
421 | |||
413 | m_clientThread = new Thread(new ThreadStart(AuthUser)); | 422 | m_clientThread = new Thread(new ThreadStart(AuthUser)); |
414 | m_clientThread.Name = "ClientThread"; | 423 | m_clientThread.Name = "ClientThread"; |
415 | m_clientThread.IsBackground = true; | 424 | m_clientThread.IsBackground = true; |
@@ -654,6 +663,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
654 | 663 | ||
655 | # endregion | 664 | # endregion |
656 | 665 | ||
666 | protected int m_terrainCheckerCount = 0; | ||
657 | /// <summary> | 667 | /// <summary> |
658 | /// Event handler for check client timer | 668 | /// Event handler for check client timer |
659 | /// checks to ensure that the client is still connected | 669 | /// checks to ensure that the client is still connected |
@@ -685,7 +695,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
685 | m_probesWithNoIngressPackets = 0; | 695 | m_probesWithNoIngressPackets = 0; |
686 | m_lastPacketsReceived = m_packetsReceived; | 696 | m_lastPacketsReceived = m_packetsReceived; |
687 | } | 697 | } |
698 | |||
688 | //SendPacketStats(); | 699 | //SendPacketStats(); |
700 | m_packetTracker.Process(); | ||
701 | |||
702 | if (m_terrainCheckerCount >= 4) | ||
703 | { | ||
704 | m_packetTracker.TerrainPacketCheck(); | ||
705 | // m_packetTracker.PrimPacketCheck(); | ||
706 | m_terrainCheckerCount = -1; | ||
707 | } | ||
708 | m_terrainCheckerCount++; | ||
689 | } | 709 | } |
690 | 710 | ||
691 | # region Setup | 711 | # region Setup |
@@ -934,6 +954,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
934 | public event SetScriptRunning OnSetScriptRunning; | 954 | public event SetScriptRunning OnSetScriptRunning; |
935 | public event UpdateVector OnAutoPilotGo; | 955 | public event UpdateVector OnAutoPilotGo; |
936 | 956 | ||
957 | public event TerrainUnacked OnUnackedTerrain; | ||
958 | |||
937 | #region Scene/Avatar to Client | 959 | #region Scene/Avatar to Client |
938 | 960 | ||
939 | /// <summary> | 961 | /// <summary> |
@@ -1083,29 +1105,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1083 | public virtual void SendLayerData(float[] map) | 1105 | public virtual void SendLayerData(float[] map) |
1084 | { | 1106 | { |
1085 | ThreadPool.QueueUserWorkItem(new WaitCallback(DoSendLayerData), (object)map); | 1107 | ThreadPool.QueueUserWorkItem(new WaitCallback(DoSendLayerData), (object)map); |
1086 | //try | 1108 | |
1087 | //{ | ||
1088 | // int[] patches = new int[4]; | ||
1089 | |||
1090 | // for (int y = 0; y < 16; y++) | ||
1091 | // { | ||
1092 | // for (int x = 0; x < 16; x += 4) | ||
1093 | // { | ||
1094 | // patches[0] = x + 0 + y * 16; | ||
1095 | // patches[1] = x + 1 + y * 16; | ||
1096 | // patches[2] = x + 2 + y * 16; | ||
1097 | // patches[3] = x + 3 + y * 16; | ||
1098 | |||
1099 | // Packet layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); | ||
1100 | // OutPacket(layerpack, ThrottleOutPacketType.Land); | ||
1101 | // } | ||
1102 | // } | ||
1103 | //} | ||
1104 | //catch (Exception e) | ||
1105 | //{ | ||
1106 | // m_log.Warn("[client]: " + | ||
1107 | // "ClientView.API.cs: SendLayerData() - Failed with exception " + e.ToString()); | ||
1108 | //} | ||
1109 | } | 1109 | } |
1110 | 1110 | ||
1111 | /// <summary> | 1111 | /// <summary> |
@@ -1166,6 +1166,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1166 | /// <param name="map">heightmap</param> | 1166 | /// <param name="map">heightmap</param> |
1167 | public void SendLayerData(int px, int py, float[] map) | 1167 | public void SendLayerData(int px, int py, float[] map) |
1168 | { | 1168 | { |
1169 | SendLayerData(px, py, map, true); | ||
1170 | } | ||
1171 | |||
1172 | public void SendLayerData(int px, int py, float[] map, bool track) | ||
1173 | { | ||
1169 | try | 1174 | try |
1170 | { | 1175 | { |
1171 | int[] patches = new int[1]; | 1176 | int[] patches = new int[1]; |
@@ -1177,6 +1182,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1177 | 1182 | ||
1178 | LayerDataPacket layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); | 1183 | LayerDataPacket layerpack = LLClientView.TerrainManager.CreateLandPacket(map, patches); |
1179 | layerpack.Header.Zerocoded = true; | 1184 | layerpack.Header.Zerocoded = true; |
1185 | |||
1186 | if (track) | ||
1187 | { | ||
1188 | layerpack.Header.Sequence = NextSeqNum(); | ||
1189 | m_packetTracker.TrackTerrainPacket(layerpack.Header.Sequence, px, py); | ||
1190 | } | ||
1191 | |||
1180 | OutPacket(layerpack, ThrottleOutPacketType.Land); | 1192 | OutPacket(layerpack, ThrottleOutPacketType.Land); |
1181 | } | 1193 | } |
1182 | catch (Exception e) | 1194 | catch (Exception e) |
@@ -2297,14 +2309,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2297 | ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, | 2309 | ulong regionHandle, ushort timeDilation, uint localID, PrimitiveBaseShape primShape, |
2298 | LLVector3 pos, LLVector3 vel, LLVector3 acc, LLQuaternion rotation, LLVector3 rvel, | 2310 | LLVector3 pos, LLVector3 vel, LLVector3 acc, LLQuaternion rotation, LLVector3 rvel, |
2299 | uint flags, LLUUID objectID, LLUUID ownerID, string text, byte[] color, | 2311 | uint flags, LLUUID objectID, LLUUID ownerID, string text, byte[] color, |
2300 | uint parentID, byte[] particleSystem, byte clickAction) | 2312 | uint parentID, byte[] particleSystem, byte clickAction, bool track) |
2301 | { | 2313 | { |
2302 | byte[] textureanim = new byte[0]; | 2314 | byte[] textureanim = new byte[0]; |
2303 | 2315 | ||
2304 | SendPrimitiveToClient(regionHandle, timeDilation, localID, primShape, pos, vel, | 2316 | SendPrimitiveToClient(regionHandle, timeDilation, localID, primShape, pos, vel, |
2305 | acc, rotation, rvel, flags, | 2317 | acc, rotation, rvel, flags, |
2306 | objectID, ownerID, text, color, parentID, particleSystem, | 2318 | objectID, ownerID, text, color, parentID, particleSystem, |
2307 | clickAction, textureanim, false, (uint)0, LLUUID.Zero, LLUUID.Zero, 0, 0, 0); | 2319 | clickAction, textureanim, false, (uint)0, LLUUID.Zero, LLUUID.Zero, 0, 0, 0, track); |
2308 | } | 2320 | } |
2309 | 2321 | ||
2310 | public void SendPrimitiveToClient( | 2322 | public void SendPrimitiveToClient( |
@@ -2312,8 +2324,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2312 | LLVector3 pos, LLVector3 velocity, LLVector3 acceleration, LLQuaternion rotation, LLVector3 rotational_velocity, | 2324 | LLVector3 pos, LLVector3 velocity, LLVector3 acceleration, LLQuaternion rotation, LLVector3 rotational_velocity, |
2313 | uint flags, | 2325 | uint flags, |
2314 | LLUUID objectID, LLUUID ownerID, string text, byte[] color, uint parentID, byte[] particleSystem, | 2326 | LLUUID objectID, LLUUID ownerID, string text, byte[] color, uint parentID, byte[] particleSystem, |
2315 | byte clickAction, byte[] textureanim, bool attachment, uint AttachPoint, LLUUID AssetId, LLUUID SoundId, double SoundGain, byte SoundFlags, double SoundRadius) | 2327 | byte clickAction, byte[] textureanim, bool attachment, uint AttachPoint, LLUUID AssetId, LLUUID SoundId, double SoundGain, byte SoundFlags, double SoundRadius, bool track) |
2316 | { | 2328 | { |
2329 | |||
2317 | if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0) | 2330 | if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0) |
2318 | rotation = LLQuaternion.Identity; | 2331 | rotation = LLQuaternion.Identity; |
2319 | 2332 | ||
@@ -2396,6 +2409,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
2396 | outPacket.ObjectData[0].TextureAnim = textureanim; | 2409 | outPacket.ObjectData[0].TextureAnim = textureanim; |
2397 | } | 2410 | } |
2398 | outPacket.Header.Zerocoded = true; | 2411 | outPacket.Header.Zerocoded = true; |
2412 | |||
2413 | if (track) | ||
2414 | { | ||
2415 | outPacket.Header.Sequence = NextSeqNum(); | ||
2416 | m_packetTracker.TrackPrimPacket(outPacket.Header.Sequence, objectID); | ||
2417 | } | ||
2418 | |||
2399 | OutPacket(outPacket, ThrottleOutPacketType.Task); | 2419 | OutPacket(outPacket, ThrottleOutPacketType.Task); |
2400 | } | 2420 | } |
2401 | 2421 | ||
@@ -3816,7 +3836,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3816 | 3836 | ||
3817 | if (!Pack.Header.Resent) | 3837 | if (!Pack.Header.Resent) |
3818 | { | 3838 | { |
3819 | Pack.Header.Sequence = NextSeqNum(); | 3839 | if (Pack.Header.Sequence == 0) |
3840 | { | ||
3841 | Pack.Header.Sequence = NextSeqNum(); | ||
3842 | } | ||
3820 | 3843 | ||
3821 | if (Pack.Header.Reliable) //DIRTY HACK | 3844 | if (Pack.Header.Reliable) //DIRTY HACK |
3822 | { | 3845 | { |
@@ -3878,13 +3901,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3878 | { | 3901 | { |
3879 | foreach (uint ackedPacketId in NewPack.Header.AckList) | 3902 | foreach (uint ackedPacketId in NewPack.Header.AckList) |
3880 | { | 3903 | { |
3881 | Packet ackedPacket; | 3904 | RemovePacketFromNeedAckList(ackedPacketId); |
3882 | |||
3883 | if (m_needAck.TryGetValue(ackedPacketId, out ackedPacket)) | ||
3884 | { | ||
3885 | m_unAckedBytes -= ackedPacket.ToBytes().Length; | ||
3886 | m_needAck.Remove(ackedPacketId); | ||
3887 | } | ||
3888 | } | 3905 | } |
3889 | } | 3906 | } |
3890 | } | 3907 | } |
@@ -3899,12 +3916,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3899 | foreach (PacketAckPacket.PacketsBlock block in ackPacket.Packets) | 3916 | foreach (PacketAckPacket.PacketsBlock block in ackPacket.Packets) |
3900 | { | 3917 | { |
3901 | uint ackedPackId = block.ID; | 3918 | uint ackedPackId = block.ID; |
3902 | Packet ackedPacket; | 3919 | RemovePacketFromNeedAckList(ackedPackId); |
3903 | if (m_needAck.TryGetValue(ackedPackId, out ackedPacket)) | ||
3904 | { | ||
3905 | m_unAckedBytes -= ackedPacket.ToBytes().Length; | ||
3906 | m_needAck.Remove(ackedPackId); | ||
3907 | } | ||
3908 | } | 3920 | } |
3909 | } | 3921 | } |
3910 | } | 3922 | } |
@@ -3926,6 +3938,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3926 | } | 3938 | } |
3927 | } | 3939 | } |
3928 | 3940 | ||
3941 | private void RemovePacketFromNeedAckList(uint ackedPackId) | ||
3942 | { | ||
3943 | Packet ackedPacket; | ||
3944 | if (m_needAck.TryGetValue(ackedPackId, out ackedPacket)) | ||
3945 | { | ||
3946 | m_unAckedBytes -= ackedPacket.ToBytes().Length; | ||
3947 | m_needAck.Remove(ackedPackId); | ||
3948 | |||
3949 | m_packetTracker.PacketAck(ackedPackId); | ||
3950 | } | ||
3951 | } | ||
3952 | |||
3929 | /// <summary> | 3953 | /// <summary> |
3930 | /// The dreaded OutPacket. This should only be called from withink the ClientStack itself right now | 3954 | /// The dreaded OutPacket. This should only be called from withink the ClientStack itself right now |
3931 | /// This is the entry point for simulator packets to go out to the client. | 3955 | /// This is the entry point for simulator packets to go out to the client. |
@@ -4037,6 +4061,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4037 | SendAcks(); | 4061 | SendAcks(); |
4038 | ResendUnacked(); | 4062 | ResendUnacked(); |
4039 | SendPacketStats(); | 4063 | SendPacketStats(); |
4064 | // TerrainPacketTrack(); | ||
4040 | } | 4065 | } |
4041 | 4066 | ||
4042 | /// <summary> | 4067 | /// <summary> |
@@ -4053,6 +4078,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4053 | } | 4078 | } |
4054 | } | 4079 | } |
4055 | 4080 | ||
4081 | |||
4056 | /// <summary> | 4082 | /// <summary> |
4057 | /// Emties out the old packets in the packet duplication tracking table. | 4083 | /// Emties out the old packets in the packet duplication tracking table. |
4058 | /// </summary> | 4084 | /// </summary> |
@@ -4092,6 +4118,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4092 | 4118 | ||
4093 | #endregion | 4119 | #endregion |
4094 | 4120 | ||
4121 | public void TriggerTerrainUnackedEvent(int patchX, int patchY) | ||
4122 | { | ||
4123 | handlerUnackedTerrain = OnUnackedTerrain; | ||
4124 | if (handlerUnackedTerrain != null) | ||
4125 | { | ||
4126 | handlerUnackedTerrain(this, patchX, patchY); | ||
4127 | } | ||
4128 | } | ||
4129 | |||
4095 | // Previously ClientView.ProcessPackets | 4130 | // Previously ClientView.ProcessPackets |
4096 | 4131 | ||
4097 | public bool AddMoney(int debit) | 4132 | public bool AddMoney(int debit) |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLPacketTracker.cs b/OpenSim/Region/ClientStack/LindenUDP/LLPacketTracker.cs new file mode 100644 index 0000000..e775a67 --- /dev/null +++ b/OpenSim/Region/ClientStack/LindenUDP/LLPacketTracker.cs | |||
@@ -0,0 +1,234 @@ | |||
1 | using System; | ||
2 | using System.Collections.Generic; | ||
3 | using System.Text; | ||
4 | using System.Threading; | ||
5 | using libsecondlife; | ||
6 | |||
7 | namespace OpenSim.Region.ClientStack.LindenUDP | ||
8 | { | ||
9 | |||
10 | public class LLPacketTracker | ||
11 | { | ||
12 | public delegate void PacketAcked(uint sequenceNumber); | ||
13 | public event PacketAcked OnPacketAcked; | ||
14 | |||
15 | protected List<uint> m_beenAcked = new List<uint>(); | ||
16 | |||
17 | protected TerrainPacketTracker[,] m_sentTerrainPackets = new TerrainPacketTracker[16, 16]; | ||
18 | protected Dictionary<LLUUID, PrimPacketTracker> m_sendPrimPackets = new Dictionary<LLUUID, PrimPacketTracker>(); | ||
19 | |||
20 | protected LLClientView m_parentClient; | ||
21 | |||
22 | public LLPacketTracker(LLClientView parent) | ||
23 | { | ||
24 | m_parentClient = parent; | ||
25 | OnPacketAcked += TerrainPacketAcked; | ||
26 | //OnPacketAcked += PrimPacketAcked; | ||
27 | } | ||
28 | |||
29 | public void PacketAck(uint sequenceNumber) | ||
30 | { | ||
31 | lock (m_beenAcked) | ||
32 | { | ||
33 | m_beenAcked.Add(sequenceNumber); | ||
34 | } | ||
35 | } | ||
36 | |||
37 | public void TrackTerrainPacket(uint sequenceNumber, int patchX, int patchY) | ||
38 | { | ||
39 | TerrainPacketTracker tracker = new TerrainPacketTracker(); | ||
40 | tracker.X = patchX; | ||
41 | tracker.Y = patchY; | ||
42 | tracker.SeqNumber = sequenceNumber; | ||
43 | tracker.TimeSent = DateTime.Now; | ||
44 | lock (m_sentTerrainPackets) | ||
45 | { | ||
46 | m_sentTerrainPackets[patchX, patchY] = tracker; | ||
47 | } | ||
48 | } | ||
49 | |||
50 | public void TrackPrimPacket(uint sequenceNumber, LLUUID primID) | ||
51 | { | ||
52 | PrimPacketTracker tracker = new PrimPacketTracker(); | ||
53 | tracker.PrimID = primID; | ||
54 | tracker.TimeSent = DateTime.Now; | ||
55 | tracker.SeqNumber = sequenceNumber; | ||
56 | lock (m_sendPrimPackets) | ||
57 | { | ||
58 | m_sendPrimPackets[primID] = tracker; | ||
59 | } | ||
60 | } | ||
61 | |||
62 | public void TerrainPacketCheck() | ||
63 | { | ||
64 | DateTime now = DateTime.Now; | ||
65 | List<TerrainPacketTracker> resendList = new List<TerrainPacketTracker>(); | ||
66 | lock (m_sentTerrainPackets) | ||
67 | { | ||
68 | for (int y = 0; y < 16; y++) | ||
69 | { | ||
70 | for (int x = 0; x < 16; x++) | ||
71 | { | ||
72 | if (m_sentTerrainPackets[x, y] != null) | ||
73 | { | ||
74 | TerrainPacketTracker tracker = m_sentTerrainPackets[x, y]; | ||
75 | if ((now - tracker.TimeSent) > TimeSpan.FromMinutes(1)) | ||
76 | { | ||
77 | tracker.TimeSent = now; | ||
78 | m_sentTerrainPackets[x, y] = null; | ||
79 | resendList.Add(tracker); | ||
80 | } | ||
81 | } | ||
82 | } | ||
83 | } | ||
84 | } | ||
85 | |||
86 | foreach (TerrainPacketTracker tracker in resendList) | ||
87 | { | ||
88 | m_parentClient.TriggerTerrainUnackedEvent(tracker.X, tracker.Y); | ||
89 | } | ||
90 | } | ||
91 | |||
92 | public void PrimPacketCheck() | ||
93 | { | ||
94 | DateTime now = DateTime.Now; | ||
95 | List<PrimPacketTracker> resendList = new List<PrimPacketTracker>(); | ||
96 | List<PrimPacketTracker> ackedList = new List<PrimPacketTracker>(); | ||
97 | |||
98 | lock (m_sendPrimPackets) | ||
99 | { | ||
100 | foreach (PrimPacketTracker tracker in m_sendPrimPackets.Values) | ||
101 | { | ||
102 | if (tracker.Acked) | ||
103 | { | ||
104 | ackedList.Add(tracker); | ||
105 | } | ||
106 | else if (((now - tracker.TimeSent) > TimeSpan.FromMinutes(1)) && (!tracker.Acked)) | ||
107 | { | ||
108 | resendList.Add(tracker); | ||
109 | } | ||
110 | } | ||
111 | } | ||
112 | |||
113 | foreach (PrimPacketTracker tracker in resendList) | ||
114 | { | ||
115 | lock (m_sendPrimPackets) | ||
116 | { | ||
117 | m_sendPrimPackets.Remove(tracker.PrimID); | ||
118 | } | ||
119 | //call event | ||
120 | Console.WriteLine("Prim packet not acked, " + tracker.PrimID.ToString()); | ||
121 | } | ||
122 | |||
123 | |||
124 | RemovePrimTrackers(ackedList); | ||
125 | } | ||
126 | |||
127 | public void PrimTrackerCleanup() | ||
128 | { | ||
129 | List<PrimPacketTracker> ackedList = new List<PrimPacketTracker>(); | ||
130 | |||
131 | lock (m_sendPrimPackets) | ||
132 | { | ||
133 | foreach (PrimPacketTracker tracker in m_sendPrimPackets.Values) | ||
134 | { | ||
135 | if (tracker.Acked) | ||
136 | { | ||
137 | ackedList.Add(tracker); | ||
138 | } | ||
139 | } | ||
140 | } | ||
141 | Thread.Sleep(15); //give a little bit of time for other code to access list before we lock it again | ||
142 | |||
143 | RemovePrimTrackers(ackedList); | ||
144 | } | ||
145 | |||
146 | protected void RemovePrimTrackers(List<PrimPacketTracker> ackedList) | ||
147 | { | ||
148 | lock (m_sendPrimPackets) | ||
149 | { | ||
150 | foreach (PrimPacketTracker tracker in ackedList) | ||
151 | { | ||
152 | m_sendPrimPackets.Remove(tracker.PrimID); | ||
153 | } | ||
154 | } | ||
155 | } | ||
156 | |||
157 | protected void TerrainPacketAcked(uint sequence) | ||
158 | { | ||
159 | lock (m_sentTerrainPackets) | ||
160 | { | ||
161 | for (int y = 0; y < 16; y++) | ||
162 | { | ||
163 | for (int x = 0; x < 16; x++) | ||
164 | { | ||
165 | if (m_sentTerrainPackets[x, y] != null) | ||
166 | { | ||
167 | if (m_sentTerrainPackets[x, y].SeqNumber == sequence) | ||
168 | { | ||
169 | m_sentTerrainPackets[x, y] = null; | ||
170 | return; | ||
171 | } | ||
172 | } | ||
173 | } | ||
174 | } | ||
175 | } | ||
176 | } | ||
177 | |||
178 | protected void PrimPacketAcked(uint sequence) | ||
179 | { | ||
180 | lock (m_sendPrimPackets) | ||
181 | { | ||
182 | foreach (PrimPacketTracker tracker in m_sendPrimPackets.Values) | ||
183 | { | ||
184 | if (tracker.SeqNumber == sequence) | ||
185 | { | ||
186 | tracker.Acked = true; | ||
187 | break; | ||
188 | } | ||
189 | } | ||
190 | } | ||
191 | } | ||
192 | |||
193 | public void Process() | ||
194 | { | ||
195 | List<uint> ackedPackets = null; | ||
196 | lock (m_beenAcked) | ||
197 | { | ||
198 | ackedPackets = new List<uint>(m_beenAcked); | ||
199 | m_beenAcked.Clear(); | ||
200 | } | ||
201 | |||
202 | if (ackedPackets != null) | ||
203 | { | ||
204 | foreach (uint packetId in ackedPackets) | ||
205 | { | ||
206 | if (OnPacketAcked != null) | ||
207 | { | ||
208 | OnPacketAcked(packetId); | ||
209 | } | ||
210 | } | ||
211 | } | ||
212 | |||
213 | // ackedPackets.Clear(); | ||
214 | ackedPackets = null; | ||
215 | } | ||
216 | |||
217 | public class TerrainPacketTracker | ||
218 | { | ||
219 | public uint SeqNumber = 0; | ||
220 | public int X; | ||
221 | public int Y; | ||
222 | public DateTime TimeSent; | ||
223 | |||
224 | } | ||
225 | |||
226 | public class PrimPacketTracker | ||
227 | { | ||
228 | public uint SeqNumber = 0; | ||
229 | public DateTime TimeSent; | ||
230 | public LLUUID PrimID; | ||
231 | public bool Acked = false; | ||
232 | } | ||
233 | } | ||
234 | } | ||