corrade-vassal – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 vero 1 /*
2 * Copyright (c) 2006-2014, openmetaverse.org
3 * All rights reserved.
4 *
5 * - Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * - Redistributions of source code must retain the above copyright notice, this
9 * list of conditions and the following disclaimer.
10 * - Neither the name of the openmetaverse.org nor the names
11 * of its contributors may be used to endorse or promote products derived from
12 * this software without specific prior written permission.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24 * POSSIBILITY OF SUCH DAMAGE.
25 */
26  
27 using System;
28 using System.IO;
29 using System.Net;
30 using System.Linq;
31 using System.Collections;
32 using System.Collections.Generic;
33 using System.ComponentModel;
34 using System.Text.RegularExpressions;
35 using System.Drawing;
36 using System.Text;
37 using System.Windows.Forms;
38 using System.Reflection;
39 using System.Threading;
40 using GridProxy;
41 using OpenMetaverse;
42 using OpenMetaverse.Packets;
43 using OpenMetaverse.StructuredData;
44 using OpenMetaverse.Interfaces;
45 using System.Xml;
46 using Nwc.XmlRpc;
47 using Logger = OpenMetaverse.Logger;
48  
49 namespace WinGridProxy
50 {
51 public partial class FormWinGridProxy : Form
52 {
53 // only allow one thread at a time to do file I/O operations
54 private object m_FileIOLockerObject = new object();
55  
56 // Class for saving and restoring settings
57 private static SettingsStore Store = new SettingsStore();
58  
59 private static bool m_ProxyRunning;
60  
61 private Assembly m_CurrentAssembly = Assembly.GetExecutingAssembly();
62  
63 ProxyManager proxy;
64  
65 private FormPluginManager pluginManager;
66  
67 private int PacketCounter;
68  
69 // stats tracking
70 private int CapsInCounter;
71 private int CapsInBytes;
72 private int CapsOutCounter;
73 private int CapsOutBytes;
74 private int PacketsInCounter;
75 private int PacketsInBytes;
76 private int PacketsOutCounter;
77 private int PacketsOutBytes;
78  
79 private List<ListViewItem> QueuedSessions;
80 private bool monoRuntime;
81  
82 private const string PROTO_CAPABILITIES = "Cap";
83 private const string PROTO_EVENTMESSAGE = "Event";
84 private const string PROTO_PACKETSTRING = "UDP";
85 private const string PROTO_AUTHENTICATE = "https";
86  
87 // some default colors for session items
88 private readonly Color Color_Login = Color.OldLace;
89 private readonly Color Color_Packet = Color.LightYellow;
90 private readonly Color Color_Cap = Color.Honeydew;
91 private readonly Color Color_Event = Color.AliceBlue;
92  
93 public FormWinGridProxy()
94 {
95 InitializeComponent();
96  
97 Logger.Log("WinGridProxy ready", Helpers.LogLevel.Info);
98  
99 if (FireEventAppender.Instance != null)
100 {
101 FireEventAppender.Instance.MessageLoggedEvent += new MessageLoggedEventHandler(Instance_MessageLoggedEvent);
102 }
103  
104 // Attempt to work around some mono bugs
105 monoRuntime = Type.GetType("Mono.Runtime") != null; // Officially supported way of detecting mono
106 if (monoRuntime)
107 {
108 Font fixedFont = new Font(FontFamily.GenericMonospace, 9f, FontStyle.Regular, GraphicsUnit.Point);
109 richTextBoxDecodedRequest.Font =
110 richTextBoxDecodedResponse.Font =
111 richTextBoxNotationRequest.Font =
112 richTextBoxNotationResponse.Font =
113 richTextBoxRawRequest.Font =
114 richTextBoxRawResponse.Font = fixedFont;
115 }
116  
117 QueuedSessions = new List<ListViewItem>();
118  
119 // populate the listen box with the known IP Addresses of this host
120 IPHostEntry iphostentry = Dns.GetHostByName(Dns.GetHostName());
121 foreach (IPAddress address in iphostentry.AddressList)
122 comboBoxListenAddress.Items.Add(address.ToString());
123  
124 ProxyManager.OnPacketLog += ProxyManager_OnPacketLog;
125 ProxyManager.OnMessageLog += ProxyManager_OnMessageLog;
126 ProxyManager.OnLoginResponse += ProxyManager_OnLoginResponse;
127 ProxyManager.OnCapabilityAdded += ProxyManager_OnCapabilityAdded;
128 ProxyManager.OnEventMessageLog += ProxyManager_OnEventMessageLog;
129 }
130  
131 #region Event Handlers for Messages/Packets
132  
133 /// <summary>
134 /// Adds a new EventQueue message to the Message Filters listview.
135 /// </summary>
136 /// <param name="req"></param>
137 /// <param name="stage"></param>
138 void ProxyManager_OnEventMessageLog(CapsRequest req, CapsStage stage)
139 {
140 if (this.InvokeRequired)
141 {
142 this.BeginInvoke(new MethodInvoker(() => ProxyManager_OnEventMessageLog(req, stage)));
143 }
144 else
145 {
146 ListViewItem foundCap = FindListViewItem(listViewMessageFilters, req.Info.CapType, false);
147  
148 if (foundCap == null)
149 {
150 ListViewItem addedItem = listViewMessageFilters.Items.Add(new ListViewItem(req.Info.CapType,
151 listViewMessageFilters.Groups["EventQueueMessages"]));
152  
153 addedItem.SubItems.Add(PROTO_EVENTMESSAGE);
154 addedItem.BackColor = Color_Event;
155  
156 if (autoAddNewDiscoveredMessagesToolStripMenuItem.Checked)
157 addedItem.Checked = true;
158 }
159 else
160 {
161 ProxyManager_OnMessageLog(req, CapsStage.Response);
162 }
163 }
164 }
165  
166 /// <summary>
167 /// Adds a new Capability message to the message filters listview
168 /// </summary>
169 private void ProxyManager_OnCapabilityAdded(CapInfo cap)
170 {
171 if (this.InvokeRequired)
172 {
173 this.BeginInvoke(new MethodInvoker(() => ProxyManager_OnCapabilityAdded(cap)));
174 }
175 else
176 {
177 ListViewItem foundCap = FindListViewItem(listViewMessageFilters, cap.CapType, false);
178 if (foundCap == null)
179 {
180 ListViewItem addedItem = listViewMessageFilters.Items.Add(new ListViewItem(cap.CapType,
181 listViewMessageFilters.Groups["Capabilities"]));
182 addedItem.SubItems.Add(PROTO_CAPABILITIES);
183 addedItem.BackColor = Color_Cap;
184  
185 if (autoAddNewDiscoveredMessagesToolStripMenuItem.Checked)
186 addedItem.Checked = true;
187 }
188 }
189 }
190  
191 /// <summary>
192 /// Handle Login Requests/Responses
193 /// </summary>
194 private void ProxyManager_OnLoginResponse(object request, Direction direction)
195 {
196 if (this.InvokeRequired)
197 {
198 this.BeginInvoke(new MethodInvoker(() => ProxyManager_OnLoginResponse(request, direction)));
199 }
200 else
201 {
202 string loginType;
203  
204 if (request is XmlRpcRequest)
205 {
206 loginType = "Login Request";
207 }
208 else
209 {
210 loginType = "Login Response";
211 }
212  
213 ListViewItem foundItem = FindListViewItem(listViewPacketFilters, loginType, false);
214  
215 if (foundItem != null && foundItem.Checked == true)
216 {
217 PacketCounter++;
218  
219 SessionLogin sessionLogin = new SessionLogin(request, direction, comboBoxLoginURL.Text, request.GetType().Name + " " + loginType);
220  
221 ListViewItem sessionEntry = new ListViewItem(new string[] { PacketCounter.ToString(), sessionLogin.TimeStamp.ToString("HH:mm:ss.fff"),
222 sessionLogin.Protocol, sessionLogin.Name, sessionLogin.Length.ToString(), sessionLogin.Host, sessionLogin.ContentType });
223  
224 sessionEntry.Tag = sessionLogin;
225 sessionEntry.ImageIndex = (int)sessionLogin.Direction;
226  
227 AddSession(sessionEntry);
228 }
229 }
230 }
231  
232 // Only raised when we've told GridProxy we want a specific packet type
233 private void ProxyManager_OnPacketLog(Packet packet, Direction direction, IPEndPoint endpoint)
234 {
235 PacketCounter++;
236  
237 if (direction == Direction.Incoming)
238 {
239 PacketsInCounter++;
240 PacketsInBytes += packet.Length;
241 }
242 else
243 {
244 PacketsOutCounter++;
245 PacketsOutBytes += packet.Length;
246 }
247  
248 SessionPacket sessionPacket = new SessionPacket(packet, direction, endpoint,
249 PacketDecoder.InterpretOptions(packet.Header) + " Seq: " + packet.Header.Sequence.ToString() + " Freq:" + packet.Header.Frequency.ToString());
250  
251 ListViewItem sessionItem = new ListViewItem(new string[] { PacketCounter.ToString(), sessionPacket.TimeStamp.ToString("HH:mm:ss.fff"), sessionPacket.Protocol, sessionPacket.Name, sessionPacket.Length.ToString(), sessionPacket.Host, sessionPacket.ContentType });
252 sessionItem.Tag = sessionPacket;
253 sessionItem.ImageIndex = (int)sessionPacket.Direction;
254  
255 AddSession(sessionItem);
256 }
257  
258 /// <summary>
259 /// Handle Capabilities
260 /// </summary>
261 private void ProxyManager_OnMessageLog(CapsRequest req, CapsStage stage)
262 {
263 if (this.InvokeRequired)
264 {
265 this.BeginInvoke(new MethodInvoker(() => ProxyManager_OnMessageLog(req, stage)));
266 }
267 else
268 {
269 ListViewItem found = FindListViewItem(listViewMessageFilters, req.Info.CapType, false);
270  
271 if (found != null && found.Checked)
272 {
273 PacketCounter++;
274  
275 int size = 0;
276 string contentType = String.Empty;
277 if (req.RawRequest != null)
278 {
279 size += req.RawRequest.Length;
280 contentType = req.RequestHeaders.Get("Content-Type"); //req.RequestHeaders["Content-Type"];
281 }
282 if (req.RawResponse != null)
283 {
284 size += req.RawResponse.Length;
285 contentType = req.ResponseHeaders.Get("Content-Type");
286 }
287  
288 Direction direction;
289 if (stage == CapsStage.Request)
290 {
291 CapsOutCounter++;
292 CapsOutBytes += req.Request.ToString().Length;
293 direction = Direction.Outgoing;
294 }
295 else
296 {
297 CapsInCounter++;
298 CapsInBytes += req.Response.ToString().Length;
299 direction = Direction.Incoming;
300 }
301  
302 string proto = found.SubItems[1].Text;
303  
304 Session capsSession = null;
305 if (found.Group.Header.Equals("Capabilities"))
306 {
307 capsSession = new SessionCaps(req.RawRequest, req.RawResponse, req.RequestHeaders,
308 req.ResponseHeaders, direction, req.Info.URI, req.Info.CapType, proto, req.FullUri);
309 }
310 else
311 {
312 capsSession = new SessionEvent(req.RawResponse, req.ResponseHeaders, req.Info.URI, req.Info.CapType, proto);
313 }
314  
315 string[] s = { PacketCounter.ToString(), capsSession.TimeStamp.ToString("HH:mm:ss.fff"), capsSession.Protocol, capsSession.Name, capsSession.Length.ToString(), capsSession.Host, capsSession.ContentType };
316 ListViewItem session = new ListViewItem(s);
317  
318 session.ImageIndex = (int)direction;
319 session.Tag = capsSession;
320  
321 session.BackColor = found.BackColor;
322  
323 AddSession(session);
324 }
325 else
326 {
327 if (found == null)
328 {
329 // must be a new event not in KnownCaps, lets add it to the listview
330 ListViewItem addedItem = listViewMessageFilters.Items.Add(new ListViewItem(req.Info.CapType));
331 addedItem.BackColor = Color_Cap;
332  
333 if (autoAddNewDiscoveredMessagesToolStripMenuItem.Checked)
334 addedItem.Checked = true;
335 }
336 }
337 }
338 }
339  
340 #endregion
341  
342 #region Helpers
343  
344 private ListViewItem FindListViewItem(ListView listView, string key, bool searchAll)
345 {
346 foreach (ListViewItem item in listView.Items)
347 {
348 if (item.Text.Equals(key)
349 || (searchAll && item.SubItems.ContainsKey(key)))
350 return item;
351 }
352 return null;
353 }
354  
355  
356 private static string FormatBytes(long bytes)
357 {
358 const int scale = 1024;
359 string[] orders = new string[] { "GB", "MB", "KB", "Bytes" };
360 long max = (long)Math.Pow(scale, orders.Length - 1);
361  
362 foreach (string order in orders)
363 {
364 if (bytes > max)
365 return string.Format("{0:##.##} {1}", decimal.Divide(bytes, max), order);
366  
367 max /= scale;
368 }
369 return "0";
370 }
371 #endregion
372  
373 #region GUI Event Handlers
374  
375 private void buttonStartProxy_Click(object sender, EventArgs e)
376 {
377 if (buttonStartProxy.Text.StartsWith("Start") && m_ProxyRunning.Equals(false))
378 {
379 proxy = new ProxyManager(textBoxProxyPort.Text, comboBoxListenAddress.Text, comboBoxLoginURL.Text);
380 // disable any gui elements
381 comboBoxListenAddress.Enabled = textBoxProxyPort.Enabled = comboBoxLoginURL.Enabled = false;
382  
383 InitProxyFilters();
384  
385 proxy.Start();
386  
387 loadFilterSelectionsToolStripMenuItem.Enabled = saveFilterSelectionsToolStripMenuItem.Enabled = true;
388  
389 // enable any gui elements
390 toolStripSplitButton1.Enabled =
391 toolStripMenuItemPlugins.Enabled = grpUDPFilters.Enabled = grpCapsFilters.Enabled = m_ProxyRunning = true;
392 buttonStartProxy.Text = "Stop Proxy";
393 buttonStartProxy.Checked = true;
394 if (enableStatisticsToolStripMenuItem.Checked && !timer1.Enabled)
395 timer1.Enabled = true;
396 }
397 else if (buttonStartProxy.Text.StartsWith("Stop") && m_ProxyRunning.Equals(true))
398 {
399 loadFilterSelectionsToolStripMenuItem.Enabled = saveFilterSelectionsToolStripMenuItem.Enabled = false;
400 // stop the proxy
401 proxy.Stop();
402 toolStripMenuItemPlugins.Enabled = grpUDPFilters.Enabled = grpCapsFilters.Enabled = m_ProxyRunning = false;
403 buttonStartProxy.Text = "Start Proxy";
404 buttonStartProxy.Checked = false;
405 comboBoxListenAddress.Enabled = textBoxProxyPort.Enabled = comboBoxLoginURL.Enabled = true;
406  
407 if (!enableStatisticsToolStripMenuItem.Checked && timer1.Enabled)
408 timer1.Enabled = false;
409 }
410 }
411  
412 private void checkBoxCheckAllPackets_CheckedChanged(object sender, EventArgs e)
413 {
414 foreach (ListViewItem item in listViewPacketFilters.Items)
415 {
416 item.Checked = checkBoxCheckAllPackets.Checked;
417 }
418 }
419  
420 private void listViewSessions_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
421 {
422  
423 if (e.IsSelected && listViewSessions.SelectedItems.Count == 1)
424 {
425 tabControlMain.SelectTab("tabPageInspect");
426  
427 object tag = e.Item.Tag;
428  
429 if (tag is Session)
430 {
431 Session session = (Session)tag;
432  
433 treeViewXmlResponse.Nodes.Clear();
434 treeViewXMLRequest.Nodes.Clear();
435  
436 Be.Windows.Forms.DynamicByteProvider responseBytes = new Be.Windows.Forms.DynamicByteProvider(session.ToBytes(Direction.Incoming));
437 richTextBoxDecodedResponse.Text = session.ToPrettyString(Direction.Incoming);
438 richTextBoxRawResponse.Text = session.ToRawString(Direction.Incoming);
439 richTextBoxNotationResponse.Text = session.ToStringNotation(Direction.Incoming);
440 hexBoxResponse.ByteProvider = responseBytes;
441 updateTreeView(session.ToXml(Direction.Incoming), treeViewXmlResponse);
442  
443 Be.Windows.Forms.DynamicByteProvider requestBytes = new Be.Windows.Forms.DynamicByteProvider(session.ToBytes(Direction.Outgoing));
444 richTextBoxDecodedRequest.Text = session.ToPrettyString(Direction.Outgoing);
445 richTextBoxRawRequest.Text = session.ToRawString(Direction.Outgoing);
446 richTextBoxNotationRequest.Text = session.ToStringNotation(Direction.Outgoing);
447 hexBoxRequest.ByteProvider = requestBytes;
448 updateTreeView(session.ToXml(Direction.Outgoing), treeViewXMLRequest);
449  
450 RequestPosition_Changed(this, EventArgs.Empty);
451 ReplyPosition_Changed(this, EventArgs.Empty);
452 }
453 else
454 {
455 richTextBoxDecodedResponse.Text = "Unknown data object encountered: " + tag.GetType().ToString();
456 }
457  
458 }
459 }
460  
461 private void Form1_FormClosing(object sender, FormClosingEventArgs e)
462 {
463 if (m_ProxyRunning)
464 proxy.Stop();
465  
466 if (saveOptionsOnExitToolStripMenuItem.Checked)
467 SaveAllSettings("settings.osd");
468 }
469  
470 // select all items in session list
471 private void sessionSelectAll_Click(object sender, EventArgs e)
472 {
473 foreach (ListViewItem item in listViewSessions.Items)
474 {
475 item.Selected = true;
476 }
477 }
478  
479 // unselect all items in session list
480 private void sessionSelectNone_Click(object sender, EventArgs e)
481 {
482 foreach (ListViewItem item in listViewSessions.Items)
483 {
484 item.Selected = false;
485 }
486 }
487  
488 // invert selection
489 private void sessionInvertSelection_Click(object sender, EventArgs e)
490 {
491 foreach (ListViewItem item in listViewSessions.Items)
492 {
493 item.Selected = !item.Selected;
494 }
495 }
496  
497 // remove all sessions
498 private void sessionRemoveAll_Click(object sender, EventArgs e)
499 {
500 listViewSessions.Items.Clear();
501 }
502  
503 // remove sessions that are currently selected
504 private void sessionRemoveSelected_Click(object sender, EventArgs e)
505 {
506 foreach (ListViewItem item in listViewSessions.Items)
507 {
508 if (item.Selected)
509 listViewSessions.Items.Remove(item);
510 }
511 }
512  
513 // remove sessions that are not currently selected
514 private void sessionRemoveUnselected_Click(object sender, EventArgs e)
515 {
516 foreach (ListViewItem item in listViewSessions.Items)
517 {
518 if (!item.Selected)
519 listViewSessions.Items.Remove(item);
520 }
521 }
522  
523 // Colorize selected sessions
524 private void sessionMarkSelected_Click(object sender, EventArgs e)
525 {
526 ToolStripMenuItem menu = (ToolStripMenuItem)sender;
527  
528 foreach (ListViewItem item in listViewSessions.Items)
529 {
530 if (item.Selected)
531 item.BackColor = Color.FromName(menu.Text);
532 }
533 sessionSelectNone_Click(sender, e);
534 }
535  
536 // Unmark selected sessions
537 private void sessionUnmarkSelected_Click(object sender, EventArgs e)
538 {
539 foreach (ListViewItem item in listViewSessions.Items)
540 {
541 if (item.Selected)
542 item.BackColor = Color.White;
543 }
544 sessionSelectNone_Click(sender, e);
545 }
546  
547 private void aboutWinGridProxyToolStripMenuItem_Click(object sender, EventArgs e)
548 {
549 AboutBox1 about = new AboutBox1();
550 about.ShowDialog();
551 }
552  
553 // Update Request Hexbox status bar with current cursor location
554 private void RequestPosition_Changed(object sender, EventArgs e)
555 {
556 if (hexBoxRequest.ByteProvider != null)
557 {
558 labelHexRequestStatus.Text = String.Format("Ln {0} Col {1} bytes {2}",
559 hexBoxRequest.CurrentLine, hexBoxRequest.CurrentPositionInLine, hexBoxRequest.ByteProvider.Length);
560 buttonSaveRequestHex.Visible = (hexBoxRequest.ByteProvider.Length > 0);
561 }
562 buttonSaveRequestHex.Visible = (hexBoxRequest.ByteProvider != null && hexBoxRequest.ByteProvider.Length > 0);
563 }
564  
565 // Update Response Hexbox status bar with current cursor location
566 void ReplyPosition_Changed(object sender, EventArgs e)
567 {
568 if (hexBoxResponse.ByteProvider != null)
569 {
570 labelHexBoxResponseStatus.Text = String.Format("Ln {0} Col {1} bytes {2}",
571 hexBoxResponse.CurrentLine, hexBoxResponse.CurrentPositionInLine, hexBoxResponse.ByteProvider.Length);
572 }
573 buttonExportRawHex.Visible = (hexBoxResponse.ByteProvider != null && hexBoxResponse.ByteProvider.Length > 0);
574 }
575  
576 // select all specified sessions by packet name
577 private void sessionSelectAllPacketType_Click(object sender, EventArgs e)
578 {
579 foreach (ListViewItem item in listViewSessions.Items)
580 {
581 if (item.SubItems[3].Text.Equals(toolStripMenuItemSelectPacketName.Tag) && !item.Selected)
582 item.Selected = true;
583 }
584 }
585  
586 // stop capturing selected filters
587 private void filterDisableByPacketName_CheckedChanged(object sender, EventArgs e)
588 {
589 if (enableDisableFilterByNameToolStripMenuItem.Tag != null)
590 {
591 ListViewItem found = FindListViewItem(listViewMessageFilters, enableDisableFilterByNameToolStripMenuItem.Tag.ToString(), false);
592  
593 if (found != null)
594 {
595 listViewMessageFilters.Items[found.Index].Checked = enableDisableFilterByNameToolStripMenuItem.Checked;
596 }
597 else
598 {
599 found = FindListViewItem(listViewPacketFilters, enableDisableFilterByNameToolStripMenuItem.Tag.ToString(), false);
600  
601 if (found != null)
602 listViewPacketFilters.Items[found.Index].Checked = enableDisableFilterByNameToolStripMenuItem.Checked;
603 }
604 }
605 }
606  
607 /// <summary>
608 /// Setup the context menu prior to it being displayed with specific entries for filtering packets/messages
609 /// </summary>
610 /// <param name="sender"></param>
611 /// <param name="e"></param>
612 private void contextMenuStripSessions_Opening(object sender, CancelEventArgs e)
613 {
614 if (listViewSessions.SelectedItems.Count == 1)
615 {
616 ListViewItem item = listViewSessions.SelectedItems[0];
617 string strPacketOrMessage = (item.SubItems[2].Text.Equals(PROTO_PACKETSTRING)) ? "Packets" : "Messages";
618  
619 enableDisableFilterByNameToolStripMenuItem.Text = String.Format("Capture {0} {1}", item.SubItems[3].Text, strPacketOrMessage);
620 toolStripMenuItemSelectPacketName.Tag = enableDisableFilterByNameToolStripMenuItem.Tag = item.SubItems[3].Text;
621  
622 toolStripMenuItemSelectPacketName.Text = String.Format("All {0} {1}", item.SubItems[3].Text, strPacketOrMessage);
623  
624 enableDisableFilterByNameToolStripMenuItem.Visible =
625 toolStripSeparatorSelectPacketProto.Visible =
626 toolStripSeparatorFilterPacketByName.Visible =
627 toolStripMenuItemSelectPacketName.Visible = true;
628  
629 // find checkstate of selected menuitem in packets or messages filters checkedListBoxes
630 bool ctxChecked = false;
631  
632 if (strPacketOrMessage.Equals("Packets"))
633 {
634 ListViewItem found = FindListViewItem(listViewPacketFilters, toolStripMenuItemSelectPacketName.Tag.ToString(), false);
635 if (found != null)
636 ctxChecked = found.Checked;
637 }
638 else if (strPacketOrMessage.Equals("Messages"))
639 {
640 ListViewItem found = FindListViewItem(listViewMessageFilters, toolStripMenuItemSelectPacketName.Tag.ToString(), false);
641 if (found != null)
642 ctxChecked = found.Checked;
643 }
644 enableDisableFilterByNameToolStripMenuItem.Checked = ctxChecked;
645 }
646 else
647 {
648 // Hide specific selection options on context menu
649 enableDisableFilterByNameToolStripMenuItem.Visible =
650 toolStripSeparatorSelectPacketProto.Visible =
651 toolStripSeparatorFilterPacketByName.Visible =
652 toolStripMenuItemSelectPacketName.Visible = false;
653 }
654  
655 if (listViewSessions.Items.Count > 0)
656 {
657 markToolStripMenuItem2.Enabled =
658 findToolStripMenuItem1.Enabled =
659 toolStripMenuSessionsRemove.Enabled =
660 selectToolStripMenuItem2.Enabled = true;
661 }
662 else
663 {
664 markToolStripMenuItem2.Enabled =
665 findToolStripMenuItem1.Enabled =
666 toolStripMenuSessionsRemove.Enabled =
667 selectToolStripMenuItem2.Enabled = false;
668 }
669 }
670  
671 private void findSessions_Click(object sender, EventArgs e)
672 {
673 FilterOptions opts = new FilterOptions((listViewSessions.SelectedItems.Count > 0));
674 FormSessionSearch search = new FormSessionSearch(ref opts);
675 search.ShowDialog();
676  
677 if (!String.IsNullOrEmpty(opts.SearchText))
678 {
679 Thread sThread = new Thread(delegate()
680 {
681 SearchSessions(opts);
682 });
683 sThread.Name = "Search";
684 sThread.Start();
685 }
686 }
687  
688 // Enable Inject button if box contains text
689 private void richTextBoxInject_TextChanged(object sender, EventArgs e)
690 {
691 buttonInjectPacket.Enabled = (richTextBoxInject.TextLength > 0);
692 }
693  
694 private void buttonInjectPacket_Click(object sender, EventArgs e)
695 {
696 proxy.InjectPacket(richTextBoxInject.Text, true);
697 }
698  
699 private void saveFilterSelectionsToolStripMenuItem_Click(object sender, EventArgs e)
700 {
701 if (saveFileDialog2.ShowDialog() == DialogResult.OK)
702 {
703 SaveAllSettings(saveFileDialog2.FileName);
704 }
705 }
706  
707 private void loadFilterSelectionsToolStripMenuItem_Click(object sender, EventArgs e)
708 {
709 if (openFileDialog2.ShowDialog() == DialogResult.OK)
710 {
711 RestoreSavedSettings(openFileDialog2.FileName);
712 if (listViewSessions.Items.Count > 0)
713 {
714 if (MessageBox.Show("Would you like to apply these settings to the current session list?",
715 "Apply Filter", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == System.Windows.Forms.DialogResult.Yes)
716 {
717 listViewSessions.BeginUpdate();
718 foreach (ListViewItem item in listViewSessions.Items)
719 {
720 ListViewItem found = FindListViewItem(listViewPacketFilters, item.SubItems[3].Text, false);
721 if (found == null)
722 found = FindListViewItem(listViewMessageFilters, item.SubItems[3].Text, false);
723  
724 if (found != null && !found.Checked)
725 listViewSessions.Items.Remove(item);
726 }
727 listViewSessions.EndUpdate();
728 }
729 }
730 }
731 }
732  
733 private void listViewMessageFilters_ItemChecked(object sender, ItemCheckedEventArgs e)
734 {
735 proxy.AddCapsDelegate(e.Item.Text, e.Item.Checked);
736 }
737  
738 private void listViewPacketFilters_ItemChecked(object sender, ItemCheckedEventArgs e)
739 {
740 if (e.Item.Group.Name.Equals("Packets"))
741 proxy.AddUDPDelegate(PacketTypeFromName(e.Item.Text), e.Item.Checked);
742 }
743  
744 private void checkBoxCheckallCaps_CheckedChanged(object sender, EventArgs e)
745 {
746 foreach (ListViewItem item in listViewMessageFilters.Items)
747 {
748 item.Checked = checkBoxCheckAllMessages.Checked;
749 }
750 }
751  
752 /// <summary>
753 /// Start/Stop the statistics gathering timer
754 /// </summary>
755 /// <param name="sender"></param>
756 /// <param name="e"></param>
757 private void enableStatisticsToolStripMenuItem_CheckedChanged(object sender, EventArgs e)
758 {
759 if (timer1.Enabled && !enableStatisticsToolStripMenuItem.Checked)
760 timer1.Enabled = false;
761  
762 if (!timer1.Enabled && enableStatisticsToolStripMenuItem.Checked)
763 timer1.Enabled = true;
764 }
765  
766 private void saveSessionArchiveToolStripMenuItem_Click(object sender, EventArgs e)
767 {
768 if (saveFileDialog1.ShowDialog() == DialogResult.OK)
769 {
770 OSDMap map = new OSDMap(1);
771 OSDArray sessionArray = new OSDArray();
772 foreach (ListViewItem item in listViewSessions.Items)
773 {
774 if (item.Tag is Session)
775 {
776 Session data = null;
777 if (item.Tag is SessionCaps)
778 {
779 data = (SessionCaps)item.Tag;
780 }
781 else if (item.Tag is SessionEvent)
782 {
783 data = (SessionEvent)item.Tag;
784 }
785 else if (item.Tag is SessionLogin)
786 {
787 data = (SessionLogin)item.Tag;
788 }
789 else if (item.Tag is SessionPacket)
790 {
791 data = (SessionPacket)item.Tag;
792 }
793 else
794 {
795 Console.WriteLine("Not a valid session type?");
796 continue;
797 }
798 //Type t = item.Tag.GetType();
799  
800 //Session data = (SessionCaps)item.Tag;
801 OSDMap session = new OSDMap();
802 //session["name"] = OSD.FromString(item.Name);
803 //session["image_index"] = OSD.FromInteger(item.ImageIndex);
804 session["id"] = OSD.FromString(item.SubItems[0].Text);
805 //session["protocol"] = OSD.FromString(item.SubItems[1].Text);
806 //session["packet"] = OSD.FromString(item.SubItems[2].Text);
807 //session["size"] = OSD.FromString(item.SubItems[3].Text);
808 //session["host"] = OSD.FromString(item.SubItems[4].Text);
809 session["type"] = OSD.FromString(data.GetType().ToString());
810 session["tag"] = OSD.FromBinary(data.Serialize());
811 sessionArray.Add(session);
812 }
813 }
814  
815 map["sessions"] = sessionArray;
816  
817 try
818 {
819 File.WriteAllText(saveFileDialog1.FileName, map.ToString());
820 }
821 catch (Exception ex)
822 {
823 MessageBox.Show("Exception occurred trying to save session archive: " + ex);
824 }
825 }
826 }
827  
828 private void loadSessionArchiveToolStripMenuItem_Click(object sender, EventArgs e)
829 {
830 if (openFileDialog1.ShowDialog() == DialogResult.OK)
831 {
832 OSDMap map = (OSDMap)OSDParser.DeserializeLLSDNotation(File.ReadAllText(openFileDialog1.FileName));
833  
834 OSDArray sessionsArray = (OSDArray)map["sessions"];
835  
836 listViewSessions.Items.Clear();
837 listViewSessions.BeginUpdate();
838 for (int i = 0; i < sessionsArray.Count; i++)
839 {
840 OSDMap session = (OSDMap)sessionsArray[i];
841  
842 Session importedSession = (Session)m_CurrentAssembly.CreateInstance(session["type"].AsString());
843 importedSession.Deserialize(session["tag"].AsBinary());
844  
845 ListViewItem addedItem = new ListViewItem(new string[] {
846 session["id"].AsString(),
847 importedSession.TimeStamp.ToString("HH:mm:ss.fff"),
848 importedSession.Protocol,
849 importedSession.Name,
850 importedSession.Length.ToString(),
851 importedSession.Host,
852 importedSession.ContentType});
853 AddSession(addedItem);
854 //addedItem.ImageIndex = session["image_index"].AsInteger();
855 addedItem.ImageIndex = (int)importedSession.Direction;
856 addedItem.BackColor = Color.GhostWhite; // give imported items a different color
857 addedItem.Tag = importedSession;
858 }
859  
860 listViewSessions.EndUpdate();
861 }
862 }
863  
864 //Generic ListView sort event used by filter listviews only
865 private void listViewFilterSorter_ColumnClick(object sender, ColumnClickEventArgs e)
866 {
867 ListView lv = (ListView)sender;
868 ListViewItemComparer columnSorter = new ListViewItemComparer();
869 columnSorter.column = e.Column;
870  
871 if ((columnSorter.bAscending = (lv.Sorting == SortOrder.Ascending)))
872 lv.Sorting = SortOrder.Descending;
873 else
874 lv.Sorting = SortOrder.Ascending;
875  
876 lv.ListViewItemSorter = columnSorter as IComparer;
877 }
878  
879 private void exitToolStripMenuItem1_Click(object sender, EventArgs e)
880 {
881 // TODO: warn if client is connected!
882  
883 this.Close();
884 }
885 #endregion GUI Event Handlers
886  
887 #region Helpers
888  
889 private void SaveAllSettings(string fileName)
890 {
891 Store.MessageSessions.Clear();
892 Store.PacketSessions.Clear();
893  
894 foreach (ListViewItem item in listViewPacketFilters.Items)
895 {
896 FilterEntryOptions entry = new FilterEntryOptions();
897 entry.Checked = item.Checked;
898 entry.Type = item.SubItems[1].Text;
899 entry.Group = item.Group.Name;
900  
901 if (!Store.PacketSessions.ContainsKey(item.Text))
902 Store.PacketSessions.Add(item.Text, entry);
903 }
904  
905 foreach (ListViewItem item in listViewMessageFilters.Items)
906 {
907 FilterEntryOptions entry = new FilterEntryOptions();
908 entry.Checked = item.Checked;
909 entry.Type = item.SubItems[1].Text;
910 entry.Group = item.Group.Name;
911  
912 if (!Store.MessageSessions.ContainsKey(item.Text))
913 Store.MessageSessions.Add(item.Text, entry);
914 }
915  
916 Store.StatisticsEnabled = enableStatisticsToolStripMenuItem.Checked;
917 Store.SaveSessionOnExit = saveOptionsOnExitToolStripMenuItem.Checked;
918 Store.AutoCheckNewCaps = autoAddNewDiscoveredMessagesToolStripMenuItem.Checked;
919  
920 Store.SerializeToFile(fileName);
921 }
922  
923 private void RestoreSavedSettings(string fileName)
924 {
925 // load saved settings from OSD Formatted file
926  
927 if (Store.DeserializeFromFile(fileName))
928 {
929 enableStatisticsToolStripMenuItem.Checked = Store.StatisticsEnabled;
930 saveOptionsOnExitToolStripMenuItem.Checked = Store.SaveSessionOnExit;
931 autoAddNewDiscoveredMessagesToolStripMenuItem.Checked = Store.AutoCheckNewCaps;
932  
933 // Update message filter listview
934 listViewMessageFilters.BeginUpdate();
935 foreach (KeyValuePair<string, FilterEntryOptions> kvp in Store.MessageSessions)
936 {
937 ListViewItem foundMessage = FindListViewItem(listViewPacketFilters, kvp.Key, false);
938 if (foundMessage == null)
939 {
940 ListViewItem addedItem = listViewMessageFilters.Items.Add(
941 new ListViewItem(kvp.Key, listViewMessageFilters.Groups[kvp.Value.Group]));
942 addedItem.Name = kvp.Key;
943 addedItem.Checked = kvp.Value.Checked;
944 addedItem.SubItems.Add(kvp.Value.Type);
945 //addedItem.Group = listViewMessageFilters.Groups[kvp.Value.Group];
946  
947 addedItem.BackColor = (kvp.Value.Type.Equals(PROTO_CAPABILITIES)) ? Color_Cap : Color_Event;
948 }
949 else
950 {
951 foundMessage.Checked = kvp.Value.Checked;
952 }
953 if (kvp.Value.Type.Equals(PROTO_CAPABILITIES))
954 {
955 proxy.AddCapsDelegate(kvp.Key, kvp.Value.Checked);
956 }
957 }
958 listViewMessageFilters.EndUpdate();
959  
960 // updateTreeView packet filter listview
961 listViewPacketFilters.BeginUpdate();
962 foreach (KeyValuePair<string, FilterEntryOptions> kvp in Store.PacketSessions)
963 {
964 ListViewItem foundPacket = FindListViewItem(listViewPacketFilters, kvp.Key, false);
965 if (foundPacket == null)
966 {
967 ListViewItem addedItem = listViewPacketFilters.Items.Add(
968 new ListViewItem(kvp.Key, listViewPacketFilters.Groups[kvp.Value.Group]));
969  
970 addedItem.Name = kvp.Key;
971 addedItem.Checked = kvp.Value.Checked;
972 addedItem.SubItems.Add(kvp.Value.Type);
973  
974 addedItem.BackColor = (kvp.Value.Type.Equals(PROTO_AUTHENTICATE)) ? Color_Login : Color_Packet;
975 }
976 else
977 {
978 foundPacket.Checked = kvp.Value.Checked;
979 }
980 if (kvp.Value.Type.Equals(PROTO_PACKETSTRING))
981 {
982 proxy.AddUDPDelegate(PacketTypeFromName(kvp.Key), kvp.Value.Checked);
983 }
984 }
985 listViewPacketFilters.EndUpdate();
986 }
987 }
988  
989 private void InitProxyFilters()
990 {
991 RestoreSavedSettings("settings.osd");
992  
993 listViewPacketFilters.BeginUpdate();
994 foreach (string name in Enum.GetNames(typeof(PacketType)))
995 {
996 ListViewItem found = FindListViewItem(listViewPacketFilters, name, false);
997 if (!String.IsNullOrEmpty(name) && found == null)
998 {
999 ListViewItem addedItem = listViewPacketFilters.Items.Add(new ListViewItem(name, listViewPacketFilters.Groups["Packets"]));
1000 addedItem.Name = name;
1001 addedItem.SubItems.Add(PROTO_PACKETSTRING);
1002 }
1003  
1004 }
1005  
1006 ListViewItem tmp;
1007 if (!listViewPacketFilters.Items.ContainsKey("Login Request"))
1008 {
1009 tmp = listViewPacketFilters.Items.Add(new ListViewItem("Login Request", listViewPacketFilters.Groups["Login"]));
1010 tmp.Name = "Login Request";
1011 tmp.BackColor = Color_Login;
1012 tmp.SubItems.Add("Login");
1013 }
1014  
1015 if (!listViewPacketFilters.Items.ContainsKey("Login Response"))
1016 {
1017 tmp = listViewPacketFilters.Items.Add(new ListViewItem("Login Response", listViewPacketFilters.Groups["Login"]));
1018 tmp.Name = "Login Response";
1019 tmp.BackColor = Color_Login;
1020 tmp.SubItems.Add("Login");
1021 }
1022  
1023 listViewPacketFilters.EndUpdate();
1024  
1025 }
1026  
1027 private static PacketType PacketTypeFromName(string name)
1028 {
1029 Type packetTypeType = typeof(PacketType);
1030 System.Reflection.FieldInfo f = packetTypeType.GetField(name);
1031 if (f == null)
1032 {//throw new ArgumentException("Bad packet type");
1033 return PacketType.Error;
1034 }
1035  
1036 return (PacketType)Enum.ToObject(packetTypeType, (int)f.GetValue(packetTypeType));
1037 }
1038  
1039 private void SearchSessions(FilterOptions opts)
1040 {
1041 if (this.InvokeRequired)
1042 {
1043 this.BeginInvoke(new MethodInvoker(() => SearchSessions(opts)));
1044 }
1045 else
1046 {
1047 int resultCount = 0;
1048  
1049 foreach (ListViewItem item in listViewSessions.Items)
1050 {
1051 if (opts.UnMarkPrevious)
1052 item.BackColor = Color.White;
1053  
1054 if (opts.SearchSelected && !item.Selected)
1055 {
1056 continue;
1057 }
1058  
1059 if (
1060 (opts.MatchCase
1061 && (item.SubItems[3].Text.Contains(opts.SearchText)
1062 /*|| TagToString(item.Tag, item.SubItems[2].Text).Contains(opts.SearchText)*/)
1063 ) // no case matching
1064 || ((item.SubItems[3].Text.ToLower().Contains(opts.SearchText.ToLower())
1065 /*|| TagToString(item.Tag, item.SubItems[2].Text).ToLower().Contains(opts.SearchText.ToLower())*/
1066 ))
1067 )
1068 {
1069 resultCount++;
1070  
1071 if (opts.MarkMatches)
1072 item.BackColor = opts.HighlightMatchColor;
1073  
1074 if (opts.SelectResults)
1075 item.Selected = true;
1076 else
1077 item.Selected = false;
1078 }
1079 }
1080  
1081 //toolStripMainLabel.Text = String.Format("Search found {0} Matches", resultCount);
1082 }
1083 }
1084  
1085 #endregion
1086  
1087 #region XML Tree
1088  
1089 private void updateTreeView(string xml, TreeView treeView)
1090 {
1091 try
1092 {
1093 treeView.Nodes.Clear();
1094  
1095 XmlDocument tmpxmldoc = new XmlDocument();
1096 tmpxmldoc.LoadXml(xml);
1097 FillTree(tmpxmldoc.DocumentElement, treeView.Nodes);
1098 treeView.ExpandAll();
1099 }
1100 catch (Exception ex)
1101 {
1102 Console.WriteLine("Error during xml conversion:" + ex.Message);
1103 }
1104 }
1105  
1106 private void FillTree(XmlNode node, TreeNodeCollection parentnode)
1107 {
1108 // End recursion if the node is a text type
1109 if (node == null || node.NodeType == XmlNodeType.Text || node.NodeType == XmlNodeType.CDATA)
1110 return;
1111  
1112 TreeNodeCollection tmptreenodecollection = AddNodeToTree(node, parentnode);
1113  
1114 // Add all the children of the current node to the treeview
1115 foreach (XmlNode tmpchildnode in node.ChildNodes)
1116 {
1117 FillTree(tmpchildnode, tmptreenodecollection);
1118 }
1119 }
1120  
1121 private TreeNodeCollection AddNodeToTree(XmlNode node, TreeNodeCollection parentnode)
1122 {
1123 TreeNode newchildnode = CreateTreeNodeFromXmlNode(node);
1124  
1125 // if nothing to add, return the parent item
1126 if (newchildnode == null) return parentnode;
1127  
1128 // add the newly created tree node to its parent
1129 if (parentnode != null) parentnode.Add(newchildnode);
1130  
1131 return newchildnode.Nodes;
1132 }
1133  
1134 private TreeNode CreateTreeNodeFromXmlNode(XmlNode node)
1135 {
1136 TreeNode tmptreenode = new TreeNode();
1137  
1138 if ((node.HasChildNodes) && (node.FirstChild.Value != null))
1139 {
1140 tmptreenode = new TreeNode(node.Name);
1141 TreeNode tmptreenode2 = new TreeNode(node.FirstChild.Value);
1142 tmptreenode.Nodes.Add(tmptreenode2);
1143 }
1144 else if (node.NodeType != XmlNodeType.CDATA)
1145 {
1146 tmptreenode = new TreeNode(node.Name);
1147 }
1148  
1149 return tmptreenode;
1150 }
1151  
1152 #endregion
1153  
1154 #region Timers
1155  
1156 private void timer1_Tick(object sender, EventArgs e)
1157 {
1158 if (this.InvokeRequired)
1159 {
1160 this.BeginInvoke(new MethodInvoker(() => timer1_Tick(sender, e)));
1161 }
1162 else
1163 {
1164 label1PacketsOut.Text = String.Format("{0} ({1} bytes)", PacketsOutCounter, PacketsOutBytes);
1165 labelPacketsIn.Text = String.Format("{0} ({1} bytes)", PacketsInCounter, PacketsInBytes);
1166 labelPacketsTotal.Text = String.Format("{0} ({1} bytes)", PacketsOutCounter + PacketsInCounter, PacketsOutBytes + PacketsInBytes);
1167  
1168 labelCapsIn.Text = String.Format("{0} ({1} bytes)", CapsInCounter, CapsInBytes);
1169 labelCapsOut.Text = String.Format("{0} ({1} bytes)", CapsOutCounter, CapsOutBytes);
1170 labelCapsTotal.Text = String.Format("{0} ({1} bytes)", CapsInCounter + CapsOutCounter, CapsOutBytes + CapsInBytes);
1171 }
1172 }
1173  
1174 private void timerSessionQueue_Tick(object sender, EventArgs e)
1175 {
1176 lock (QueuedSessions)
1177 {
1178 if (QueuedSessions.Count > 0)
1179 {
1180 listViewSessions.BeginUpdate();
1181 listViewSessions.Items.AddRange(QueuedSessions.ToArray());
1182 if (listViewSessions.Items.Count > 0 && autoscrollToolStripMenuItem.Checked)
1183 {
1184 listViewSessions.Items[listViewSessions.Items.Count - 1].EnsureVisible();
1185 }
1186 listViewSessions.EndUpdate();
1187 QueuedSessions.Clear();
1188 }
1189 }
1190 }
1191  
1192 #endregion
1193  
1194 private void EditToolStripButton_DropDownOpening(object sender, EventArgs e)
1195 {
1196 if (listViewSessions.Items.Count > 0)
1197 {
1198 toolStripMenuSessionsRemove.Enabled =
1199 removeToolStripMenuItem2.Enabled =
1200 selectToolStripMenuItem1.Enabled =
1201 saveSessionArchiveToolStripMenuItem.Enabled =
1202 toolStripMenuItemRemoveAll.Enabled = true;
1203  
1204 if (listViewSessions.SelectedItems.Count < listViewSessions.Items.Count)
1205 {
1206 toolStripMenuItemRemoveUnselected.Enabled = true;
1207 }
1208 else
1209 {
1210 toolStripMenuItemRemoveUnselected.Enabled = false;
1211 }
1212  
1213 if (listViewSessions.SelectedItems.Count > 0)
1214 {
1215 markToolStripMenuItem1.Enabled =
1216 toolStripSeparatorSelectPacketProto.Visible =
1217 toolStripMenuItemSelectPacketName.Visible =
1218 noneToolStripMenuItem2.Enabled =
1219 copyToolStripMenuItem1.Enabled =
1220 toolStripMenuItemRemoveSelected.Enabled = true;
1221 }
1222 else
1223 {
1224 markToolStripMenuItem1.Enabled =
1225 toolStripSeparatorSelectPacketProto.Visible =
1226 toolStripMenuItemSelectPacketName.Visible =
1227 noneToolStripMenuItem2.Enabled =
1228 noneToolStripMenuItem2.Enabled =
1229 copyToolStripMenuItem1.Enabled =
1230 toolStripMenuItemRemoveSelected.Enabled = false;
1231 }
1232  
1233 if (listViewSessions.SelectedItems.Count > 0
1234 && listViewSessions.SelectedItems.Count != listViewSessions.Items.Count)
1235 {
1236 toolStripMenuItemRemoveUnselected.Enabled =
1237 invertToolStripMenuItem1.Enabled =
1238 noneToolStripMenuItem2.Enabled = true;
1239 }
1240 else
1241 {
1242 toolStripMenuItemRemoveUnselected.Enabled =
1243 invertToolStripMenuItem1.Enabled =
1244 noneToolStripMenuItem2.Enabled = false;
1245 }
1246  
1247 }
1248 else
1249 {
1250 toolStripMenuSessionsRemove.Enabled =
1251 toolStripSeparatorSelectPacketProto.Visible =
1252 // toolStripMenuItemSelectProtocol.Visible =
1253 toolStripMenuItemSelectPacketName.Visible =
1254 findToolStripMenuItem.Enabled =
1255 selectToolStripMenuItem1.Enabled =
1256 removeToolStripMenuItem2.Enabled =
1257 toolStripMenuItemRemoveUnselected.Enabled =
1258 copyToolStripMenuItem1.Enabled =
1259 markToolStripMenuItem1.Enabled =
1260 saveSessionArchiveToolStripMenuItem.Enabled =
1261 toolStripMenuItemRemoveAll.Enabled = false;
1262 }
1263  
1264 if (listViewPacketFilters.Items.Count + listViewSessions.Items.Count > 0)
1265 {
1266 saveFilterSelectionsToolStripMenuItem.Enabled = true;
1267 }
1268 else
1269 {
1270 saveFilterSelectionsToolStripMenuItem.Enabled = false;
1271 }
1272  
1273 }
1274  
1275 private void autoColorizeToolStripMenuItem_Click(object sender, EventArgs e)
1276 {
1277 if (colorDialog1.ShowDialog() == DialogResult.OK)
1278 {
1279 //listview.BackColor = colorDialog1.Color;
1280 }
1281 }
1282  
1283 private void toolStripMenuItem1_Click(object sender, EventArgs e)
1284 {
1285 if (pluginManager == null)
1286 pluginManager = new FormPluginManager(proxy.Proxy);
1287  
1288 pluginManager.ShowDialog();
1289 }
1290  
1291 void Instance_MessageLoggedEvent(object sender, MessageLoggedEventArgs e)
1292 {
1293 if (this.IsDisposed || this.Disposing)
1294 return;
1295  
1296 if (InvokeRequired)
1297 {
1298 BeginInvoke(new MethodInvoker(() => Instance_MessageLoggedEvent(sender, e)));
1299 }
1300 else
1301 {
1302 string s = String.Format("{0} [{1}] {2} {3}", e.LoggingEvent.TimeStamp, e.LoggingEvent.Level,
1303 e.LoggingEvent.RenderedMessage, e.LoggingEvent.ExceptionObject);
1304 richTextBoxDebugLog.AppendText(s + "\n");
1305 }
1306 }
1307  
1308 private void richTextBoxDecodedRequest_TextChanged(object sender, EventArgs e)
1309 {
1310 RichTextBox m_rtb = (RichTextBox)sender;
1311  
1312 // don't colorize xml!
1313 if (m_rtb.Lines.Length <= 0 || m_rtb.Lines[0].StartsWith("<?xml"))
1314 return;
1315  
1316 Regex typesRegex = new Regex(@"\[(?<Type>\w+|\w+\[\])\]|\((?<Enum>.*)\)|\s-- (?<Header>\w+|\w+ \[\]) --\s|(?<BlockSep>\s\*\*\*\s)|(?<Tag>\s<\w+>\s|\s<\/\w+>\s)|(?<BlockCounter>\s\w+\[\d+\]\s)", RegexOptions.ExplicitCapture);
1317  
1318 MatchCollection matches = typesRegex.Matches(m_rtb.Text);
1319 foreach (Match match in matches)
1320 {
1321 m_rtb.SelectionStart = match.Index + 1;
1322 m_rtb.SelectionLength = match.Length - 2;
1323 m_rtb.SelectionFont = new Font(m_rtb.Font.FontFamily, m_rtb.Font.Size, FontStyle.Bold);
1324  
1325 if (!String.IsNullOrEmpty(match.Groups["Type"].Value))
1326 m_rtb.SelectionColor = Color.FromArgb(43, 145, 175);
1327 else if (!String.IsNullOrEmpty(match.Groups["Enum"].Value))
1328 m_rtb.SelectionColor = Color.FromArgb(43, 145, 175);
1329 else if (!String.IsNullOrEmpty(match.Groups["Header"].Value))
1330 {
1331 m_rtb.SelectionColor = Color.Green;
1332 m_rtb.SelectionBackColor = Color.LightSteelBlue;
1333 }
1334 else if (!String.IsNullOrEmpty(match.Groups["BlockSep"].Value))
1335 m_rtb.SelectionColor = Color.Gold;
1336 else if (!String.IsNullOrEmpty(match.Groups["Tag"].Value))
1337 {
1338 m_rtb.SelectionColor = Color.White;
1339 m_rtb.SelectionBackColor = Color.Black;
1340 }
1341 else if (!String.IsNullOrEmpty(match.Groups["BlockCounter"].Value))
1342 m_rtb.SelectionColor = Color.Green;
1343  
1344 }
1345 }
1346  
1347 private void AddSession(ListViewItem item)
1348 {
1349 lock (QueuedSessions)
1350 {
1351 QueuedSessions.Add(item);
1352 }
1353 }
1354  
1355 private void asDecodedTextToolStripMenuItem_Click(object sender, EventArgs e)
1356 {
1357 if (saveFileDialog1.ShowDialog() == DialogResult.OK)
1358 {
1359 StringBuilder outString = new StringBuilder();
1360 foreach (ListViewItem item in listViewSessions.Items)
1361 {
1362 if (item.Tag is Packet)
1363 {
1364 //outString.AppendLine(DecodePacket.PacketToString((Packet)item.Tag));
1365 outString.AppendLine(PacketDecoder.PacketToString((Packet)item.Tag));
1366 }
1367  
1368 if (item.Tag is IMessage)
1369 {
1370 IMessage msg = (IMessage)item.Tag;
1371 outString.AppendLine(msg.Serialize().ToString());
1372 }
1373  
1374 try
1375 {
1376 File.WriteAllText(saveFileDialog1.FileName, outString.ToString());
1377 }
1378 catch (Exception ex)
1379 {
1380 MessageBox.Show("Exception occurred trying to save session archive: " + ex);
1381 }
1382 }
1383 }
1384 }
1385  
1386 private void richTextBoxDecodedRequest_LinkClicked(object sender, LinkClickedEventArgs e)
1387 {
1388 System.Diagnostics.Process.Start(e.LinkText);
1389 }
1390  
1391 private void saveSettingsToolStripMenuItem_Click(object sender, EventArgs e)
1392 {
1393 SaveAllSettings("settings.osd");
1394 }
1395 // Column sorter
1396 private void listViewSessions_ColumnClick(object sender, ColumnClickEventArgs e)
1397 {
1398 ListView listView1 = (ListView)sender;
1399  
1400 ListViewSorter Sorter = new ListViewSorter();
1401 listView1.ListViewItemSorter = Sorter;
1402 if (!(listView1.ListViewItemSorter is ListViewSorter))
1403 return;
1404  
1405 Sorter = (ListViewSorter)listView1.ListViewItemSorter;
1406  
1407 if (Sorter.LastSort == e.Column)
1408 {
1409 if (listView1.Sorting == SortOrder.Ascending)
1410 listView1.Sorting = SortOrder.Descending;
1411 else
1412 listView1.Sorting = SortOrder.Ascending;
1413 }
1414 else
1415 {
1416 listView1.Sorting = SortOrder.Descending;
1417 }
1418 Sorter.ByColumn = e.Column;
1419  
1420 listView1.Sort();
1421  
1422 listView1.Columns[e.Column].Width = -2;// = listView1.Columns[e.Column].Text + " " + '\u23BC';
1423 }
1424  
1425 private void buttonSaveRequestHex_Click(object sender, EventArgs e)
1426 {
1427 if (hexBoxRequest.ByteProvider != null && hexBoxRequest.ByteProvider.Length > 0)
1428 {
1429 saveFileDialog3.FileName = listViewSessions.SelectedItems[0].Name;
1430 if (saveFileDialog3.ShowDialog() == DialogResult.OK)
1431 {
1432 byte[] bytes = new byte[hexBoxRequest.ByteProvider.Length];
1433 for (int i = 0; i < hexBoxRequest.ByteProvider.Length; i++)
1434 {
1435 bytes[i] = hexBoxRequest.ByteProvider.ReadByte(i);
1436 }
1437 File.WriteAllBytes(saveFileDialog3.FileName, bytes);
1438 }
1439 }
1440 }
1441  
1442 private void buttonExportRawHex_Click(object sender, EventArgs e)
1443 {
1444 if (hexBoxResponse.ByteProvider != null && hexBoxResponse.ByteProvider.Length > 0)
1445 {
1446 saveFileDialog3.FileName = listViewSessions.SelectedItems[0].Name;
1447 if (saveFileDialog3.ShowDialog() == DialogResult.OK)
1448 {
1449 byte[] bytes = new byte[hexBoxResponse.ByteProvider.Length];
1450 for (int i = 0; i < hexBoxResponse.ByteProvider.Length; i++)
1451 {
1452 bytes[i] = hexBoxResponse.ByteProvider.ReadByte(i);
1453 }
1454 File.WriteAllBytes(saveFileDialog3.FileName, bytes);
1455 }
1456 }
1457 else
1458 {
1459 // no bytes to read!
1460 }
1461 }
1462 }
1463  
1464 public class ListViewSorter : System.Collections.IComparer
1465 {
1466 public int Compare(object o1, object o2)
1467 {
1468 if (!(o1 is ListViewItem))
1469 return 0;
1470 if (!(o2 is ListViewItem))
1471 return 0;
1472  
1473 int result;
1474  
1475 ListViewItem lvi1 = (ListViewItem)o2;
1476 ListViewItem lvi2 = (ListViewItem)o1;
1477  
1478 if (lvi1.ListView.Columns[ByColumn].Tag == null
1479 || lvi1.ListView.Columns[ByColumn].Tag == null)
1480 {
1481 return 0;
1482 }
1483  
1484 if (lvi1.ListView.Columns[ByColumn].Tag.ToString().ToLower().Equals("number"))
1485 {
1486 float fl1 = float.Parse(lvi1.SubItems[ByColumn].Text);
1487 float fl2 = float.Parse(lvi2.SubItems[ByColumn].Text);
1488  
1489 if (lvi1.ListView.Sorting == SortOrder.Ascending)
1490 result = fl1.CompareTo(fl2);
1491 else
1492 result = fl2.CompareTo(fl1);
1493 }
1494 else if (lvi1.ListView.Columns[ByColumn].Tag.ToString().ToLower().Equals("string"))
1495 {
1496 string str1 = lvi1.SubItems[ByColumn].Text;
1497 string str2 = lvi2.SubItems[ByColumn].Text;
1498  
1499 if (lvi1.ListView.Sorting == SortOrder.Ascending)
1500 result = String.Compare(str1, str2);
1501 else
1502 result = String.Compare(str2, str1);
1503 }
1504 else
1505 {
1506 return 0;
1507 }
1508  
1509 LastSort = ByColumn;
1510  
1511 return (result);
1512 }
1513  
1514  
1515 public int ByColumn
1516 {
1517 get { return Column; }
1518 set { Column = value; }
1519 }
1520 int Column = 0;
1521  
1522 public int LastSort
1523 {
1524 get { return LastColumn; }
1525 set { LastColumn = value; }
1526 }
1527 int LastColumn = 0;
1528 }
1529 }