aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/LindenUDP/LLPacketTracker.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP/LLPacketTracker.cs')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLPacketTracker.cs234
1 files changed, 234 insertions, 0 deletions
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 @@
1using System;
2using System.Collections.Generic;
3using System.Text;
4using System.Threading;
5using libsecondlife;
6
7namespace 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}