diff --git a/Programs/GridProxyGUI/FilterScroller.cs b/Programs/GridProxyGUI/FilterScroller.cs index bc0f8d49..6eedaf88 100644 --- a/Programs/GridProxyGUI/FilterScroller.cs +++ b/Programs/GridProxyGUI/FilterScroller.cs @@ -5,37 +5,6 @@ using GridProxyGUI; namespace GridProxyGUI { - - public enum ItemType : int - { - Unknown = 0, - Login, - UDP, - Cap, - EQ - } - - public class FilterItem - { - public delegate void FilterItemChangedDelegate(object sender, EventArgs e); - public event FilterItemChangedDelegate FilterItemChanged; - bool enabled; - public bool Enabled - { - get { return enabled; } - set - { - enabled = value; - if (FilterItemChanged != null) - { - FilterItemChanged(this, EventArgs.Empty); - } - } - } - public string Name; - public ItemType Type; - } - public class FilterScroller : ScrolledWindow { ListStore store; diff --git a/Programs/GridProxyGUI/MainWindow.Persistance.cs b/Programs/GridProxyGUI/MainWindow.Persistance.cs index b96f1122..ee199e4a 100755 --- a/Programs/GridProxyGUI/MainWindow.Persistance.cs +++ b/Programs/GridProxyGUI/MainWindow.Persistance.cs @@ -2,17 +2,218 @@ using Gtk; using GridProxyGUI; using OpenMetaverse.StructuredData; +using OpenMetaverse.Packets; using System.IO; using System.IO.Compression; using System.Text; using System.Net; using System.Collections.Generic; +using System.Collections.Concurrent; + +namespace GridProxyGUI +{ + public enum ItemType : int + { + Unknown = 0, + Login, + UDP, + Cap, + EQ + } + + public class FilterItem + { + public delegate void FilterItemChangedDelegate(object sender, EventArgs e); + public event FilterItemChangedDelegate FilterItemChanged; + bool enabled; + public bool Enabled + { + get { return enabled; } + set + { + enabled = value; + if (FilterItemChanged != null) + { + FilterItemChanged(this, EventArgs.Empty); + } + } + } + public string Name; + public ItemType Type; + + public OSDMap ToOSD() + { + OSDMap ret = new OSDMap(); + + ret["name"] = Name; + ret["type"] = (int)Type; + ret["enabled"] = enabled; + + return ret; + } + + public static FilterItem FromOSD(OSDMap map) + { + var ret = new FilterItem(); + + ret.Name = map["name"]; + ret.enabled = map["enabled"]; + ret.Type = (ItemType)map["type"].AsInteger(); + + return ret; + } + } + +} public partial class MainWindow { string SessionFileName; List LoginServers = new List(); + ConcurrentDictionary UDPFilterItems = new ConcurrentDictionary(); + ConcurrentDictionary CapFilterItems = new ConcurrentDictionary(); + ListStore udpStore = new ListStore(typeof(FilterItem)); + ListStore capStore = new ListStore(typeof(FilterItem)); + FilterScroller udpScroller, capScroller; + + void LoadFromOSD(ConcurrentDictionary items, OSDArray filters) + { + try + { + foreach (var filter in filters) + { + if (filter is OSDMap) + { + var item = FilterItem.FromOSD((OSDMap)filter); + items[item.Name] = item; + } + } + } + catch { } + } + + void InitUDPFilters(OSDArray filters) + { + UDPFilterItems.Clear(); + udpStore.Clear(); + + if (filters != null) + { + LoadFromOSD(UDPFilterItems, filters); + } + + if (!UDPFilterItems.ContainsKey("Login Request")) + { + UDPFilterItems["Login Request"] = new FilterItem() { Enabled = true, Name = "Login Request", Type = ItemType.Login }; + } + + if (!UDPFilterItems.ContainsKey("Login Response")) + { + UDPFilterItems["Login Response"] = new FilterItem() { Enabled = true, Name = "Login Response", Type = ItemType.Login }; + } + + foreach (string name in Enum.GetNames(typeof(PacketType))) + { + if (!string.IsNullOrEmpty(name) && !UDPFilterItems.ContainsKey(name)) + { + var item = new FilterItem() { Enabled = false, Name = name, Type = ItemType.UDP }; + UDPFilterItems[name] = item; + } + } + + List keys = new List(UDPFilterItems.Keys); + keys.Sort((a, b) => { return string.Compare(a.ToLower(), b.ToLower()); }); + + udpStore.AppendValues(UDPFilterItems["Login Request"]); + udpStore.AppendValues(UDPFilterItems["Login Response"]); + + foreach (var key in keys) + { + UDPFilterItems[key].FilterItemChanged += item_FilterItemChanged; + if (UDPFilterItems[key].Type == ItemType.Login) continue; + udpStore.AppendValues(UDPFilterItems[key]); + } + } + + void InitCapFilters(OSDArray filters) + { + CapFilterItems.Clear(); + capStore.Clear(); + + if (filters != null) + { + LoadFromOSD(CapFilterItems, filters); + } + + List keys = new List(CapFilterItems.Keys); + keys.Sort((a, b) => + { + if (CapFilterItems[a].Type == ItemType.Cap && CapFilterItems[b].Type == ItemType.EQ) + return -1; + + if (CapFilterItems[a].Type == ItemType.EQ && CapFilterItems[b].Type == ItemType.Cap) + return 1; + + return string.Compare(a.ToLower(), b.ToLower()); + }); + + foreach (var key in keys) + { + CapFilterItems[key].FilterItemChanged += item_FilterItemChanged; + capStore.AppendValues(CapFilterItems[key]); + } + } + + void InitProxyFilters() + { + capScroller = new FilterScroller(containerFilterCap, capStore); + udpScroller = new FilterScroller(containerFilterUDP, udpStore); + + OSDArray filters = null; + + if (Options.Instance.ContainsKey("udp_filters") && Options.Instance["udp_filters"] is OSDArray) + { + filters = (OSDArray)Options.Instance["udp_filters"]; + } + InitUDPFilters(filters); + + filters = null; + if (Options.Instance.ContainsKey("cap_filters") && Options.Instance["cap_filters"] is OSDArray) + { + filters = (OSDArray)Options.Instance["cap_filters"]; + } + InitCapFilters(filters); + } + + void item_FilterItemChanged(object sender, EventArgs e) + { + if (proxy == null) return; + + FilterItem item = (FilterItem)sender; + if (item.Type == ItemType.Cap) + { + proxy.AddCapsDelegate(item.Name, item.Enabled); + } + else if (item.Type == ItemType.UDP) + { + proxy.AddUDPDelegate(item.Name, item.Enabled); + } + } + + void ApplyProxyFilters() + { + foreach (var item in UDPFilterItems.Values) + { + item_FilterItemChanged(item, EventArgs.Empty); + } + + foreach (var item in CapFilterItems.Values) + { + item_FilterItemChanged(item, EventArgs.Empty); + } + } + void LoadSavedSettings() { if (Options.Instance.ContainsKey("main_split_pos")) @@ -37,7 +238,7 @@ public partial class MainWindow { if (address.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork || address.ToString() == "127.0.0.1") continue; current++; - if (Options.Instance["listed_address"] == address.ToString()) + if (Options.Instance["listen_address"] == address.ToString()) { selected = current; } @@ -84,15 +285,60 @@ public partial class MainWindow } + internal FilterItem GetFilter(Session session) + { + if (session is SessionCaps || session is SessionEvent) + { + foreach (var filter in CapFilterItems.Values) + { + if (filter.Name == session.Name) + { + return filter; + } + } + } + else + { + foreach (var filter in UDPFilterItems.Values) + { + if (filter.Name == session.Name) + { + return filter; + } + } + } + + return null; + } + + OSDArray ListStoreToOSD(ListStore list) + { + OSDArray ret = new OSDArray(); + list.Foreach((model, path, iter) => + { + var item = model.GetValue(iter, 0) as FilterItem; + if (null != item) + { + ret.Add(item.ToOSD()); + } + + return false; + }); + return ret; + } + void SaveSettings() { + Options.Instance["udp_filters"] = ListStoreToOSD(udpStore); + Options.Instance["cap_filters"] = ListStoreToOSD(capStore); + int port = 8080; int.TryParse(txtPort.Text, out port); Options.Instance["listen_port"] = port; var currentServer = cbLoginURL.ActiveText.Trim(); Uri uriResult; - if (Uri.TryCreate(currentServer, UriKind.Absolute, out uriResult) + if (Uri.TryCreate(currentServer, UriKind.Absolute, out uriResult) && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps) && !LoginServers.Contains(currentServer)) { @@ -114,7 +360,7 @@ public partial class MainWindow Options.Instance["login_servers"] = loginServers; } - Options.Instance["listed_address"] = cbListen.ActiveText; + Options.Instance["listen_address"] = cbListen.ActiveText; Options.Instance["main_split_pos"] = mainSplit.Position; int x, y; diff --git a/Programs/GridProxyGUI/MainWindow.cs b/Programs/GridProxyGUI/MainWindow.cs index 98beef4a..c3c5098e 100755 --- a/Programs/GridProxyGUI/MainWindow.cs +++ b/Programs/GridProxyGUI/MainWindow.cs @@ -11,10 +11,6 @@ using System.Text.RegularExpressions; public partial class MainWindow : Gtk.Window { ProxyManager proxy = null; - ConcurrentDictionary UDPFilterItems = new ConcurrentDictionary(); - ConcurrentDictionary CapFilterItems = new ConcurrentDictionary(); - ListStore udpStore, capStore; - FilterScroller capScroller; MessageScroller messages; PluginsScroller plugins; @@ -71,6 +67,8 @@ public partial class MainWindow : Gtk.Window } }; + InitProxyFilters(); + txtRequest.ModifyFont(Pango.FontDescription.FromString(font)); CreateTags(txtRequest.Buffer); txtRequestRaw.ModifyFont(Pango.FontDescription.FromString(font)); @@ -82,7 +80,7 @@ public partial class MainWindow : Gtk.Window txtResponseNotation.ModifyFont(Pango.FontDescription.FromString(font)); - sessionLogScroller.Add(messages = new MessageScroller()); + sessionLogScroller.Add(messages = new MessageScroller(this)); scrolledwindowPlugin.Add(plugins = new PluginsScroller()); messages.CursorChanged += messages_CursorChanged; StatsTimer = new Timer(1000.0); @@ -170,11 +168,6 @@ public partial class MainWindow : Gtk.Window { Application.Invoke((sender, e) => { - if (null == capStore) - { - capStore = new ListStore(typeof(FilterItem)); - } - if (!CapFilterItems.ContainsKey(cap.CapType)) { FilterItem item = new FilterItem() { Name = cap.CapType, Type = ItemType.Cap }; @@ -183,11 +176,6 @@ public partial class MainWindow : Gtk.Window CapFilterItems[item.Name] = item; capStore.AppendValues(item); } - - if (null == capScroller) - { - capScroller = new FilterScroller(containerFilterCap, capStore); - } }); } @@ -195,16 +183,6 @@ public partial class MainWindow : Gtk.Window { Application.Invoke((sender, e) => { - if (null == capStore) - { - capStore = new ListStore(typeof(FilterItem)); - } - - if (null == capScroller) - { - capScroller = new FilterScroller(containerFilterCap, capStore); - } - if (!CapFilterItems.ContainsKey(req.Info.CapType)) { FilterItem item = new FilterItem() { Enabled = true, Name = req.Info.CapType, Type = ItemType.EQ }; @@ -273,19 +251,6 @@ public partial class MainWindow : Gtk.Window }); } - void item_FilterItemChanged(object sender, EventArgs e) - { - FilterItem item = (FilterItem)sender; - if (item.Type == ItemType.Cap) - { - proxy.AddCapsDelegate(item.Name, item.Enabled); - } - else if (item.Type == ItemType.UDP) - { - proxy.AddUDPDelegate(item.Name, item.Enabled); - } - } - void Logger_OnLogLine(object sender, LogEventArgs e) { Gtk.Application.Invoke((sx, ex) => @@ -308,6 +273,7 @@ public partial class MainWindow : Gtk.Window proxy = new ProxyManager(txtPort.Text, cbListen.ActiveText, cbLoginURL.ActiveText); proxy.Start(); btnLoadPlugin.Sensitive = true; + ApplyProxyFilters(); } catch (Exception ex) { @@ -315,10 +281,10 @@ public partial class MainWindow : Gtk.Window try { proxy.Stop(); - proxy = null; } catch { } btnStart.Label = "Start Proxy"; + proxy = null; } } @@ -327,10 +293,6 @@ public partial class MainWindow : Gtk.Window AppendLog("Proxy stopped" + Environment.NewLine); if (proxy != null) proxy.Stop(); proxy = null; - foreach (var child in new List(containerFilterUDP.Children)) - { - containerFilterUDP.Remove(child); - } plugins.Store.Clear(); btnLoadPlugin.Sensitive = false; } @@ -354,7 +316,6 @@ public partial class MainWindow : Gtk.Window { btnStart.Label = "Stop Proxy"; StartPoxy(); - InitProxyFilters(); } else if (btnStart.Label.StartsWith("Stop")) { @@ -363,43 +324,6 @@ public partial class MainWindow : Gtk.Window } } - void InitUDPFilters() - { - if (UDPFilterItems.Count > 0) return; - - UDPFilterItems["Login Request"] = new FilterItem() { Enabled = true, Name = "Login Request", Type = ItemType.Login }; - UDPFilterItems["Login Response"] = new FilterItem() { Enabled = true, Name = "Login Response", Type = ItemType.Login }; - foreach (string name in Enum.GetNames(typeof(PacketType))) - { - if (!string.IsNullOrEmpty(name)) - { - var item = new FilterItem() { Enabled = false, Name = name, Type = ItemType.UDP }; - UDPFilterItems[name] = item; - } - } - } - - void InitProxyFilters() - { - InitUDPFilters(); - - udpStore = new ListStore(typeof(FilterItem)); - List keys = new List(UDPFilterItems.Keys); - keys.Sort((a, b) => { return string.Compare(a.ToLower(), b.ToLower()); }); - - udpStore.AppendValues(UDPFilterItems["Login Request"]); - udpStore.AppendValues(UDPFilterItems["Login Response"]); - - foreach (var key in keys) - { - UDPFilterItems[key].FilterItemChanged += item_FilterItemChanged; - if (UDPFilterItems[key].Type == ItemType.Login) continue; - udpStore.AppendValues(UDPFilterItems[key]); - } - - new FilterScroller(containerFilterUDP, udpStore); - } - void SetAllToggles(bool on, ListStore store) { if (null == store) return; @@ -629,6 +553,12 @@ public partial class MainWindow : Gtk.Window return filters; } + public void RedrawFilters() + { + containerFilterCap.QueueDraw(); + containerFilterUDP.QueueDraw(); + } + protected void OnOpenActionActivated(object sender, EventArgs e) { var od = new Gtk.FileChooserDialog(null, "Open Session", this, FileChooserAction.Open, "Cancel", ResponseType.Cancel, "Open", ResponseType.Accept); diff --git a/Programs/GridProxyGUI/MessageScroller.cs b/Programs/GridProxyGUI/MessageScroller.cs index c42341f9..e8ccf230 100755 --- a/Programs/GridProxyGUI/MessageScroller.cs +++ b/Programs/GridProxyGUI/MessageScroller.cs @@ -11,9 +11,11 @@ namespace GridProxyGUI public ListStore Messages; public bool AutoScroll = true; + MainWindow Main; - public MessageScroller() + public MessageScroller(MainWindow main) { + this.Main = main; for (int i = 0; i < ColumnLabels.Length; i++) { @@ -54,13 +56,77 @@ namespace GridProxyGUI }; context.Add(item); - item = new MenuItem("Remove All"); - item.Activated += (sender, e) => + if (selected.Length == 1) { - Selection.UnselectAll(); - Messages.Clear(); - }; - context.Add(item); + TreeIter iter; + Messages.GetIter(out iter, selected[0]); + var session = Messages.GetValue(iter, 0) as Session; + if (session != null) + { + item = new MenuItem("Remove All " + session.Name); + item.Activated += (sender, e) => + { + TreeIter delIter; + Messages.GetIterFirst(out delIter); + + while (Messages.IterIsValid(delIter)) + { + var delSession = Messages.GetValue(delIter, 0) as Session; + if (delSession != null && delSession.GetType() == session.GetType() && delSession.Name == session.Name) + { + Messages.Remove(ref delIter); + } + else + { + Messages.IterNext(ref delIter); + } + } + }; + context.Add(item); + + item = new MenuItem("Remove and Filter Out All " + session.Name); + item.Activated += (sender, e) => + { + TreeIter delIter; + Messages.GetIterFirst(out delIter); + + FilterItem filterOut = Main.GetFilter(session); + if (filterOut != null) + { + filterOut.Enabled = false; + } + Main.RedrawFilters(); + + while (Messages.IterIsValid(delIter)) + { + var delSession = Messages.GetValue(delIter, 0) as Session; + if (delSession != null && delSession.GetType() == session.GetType() && delSession.Name == session.Name) + { + Messages.Remove(ref delIter); + } + else + { + Messages.IterNext(ref delIter); + } + } + }; + context.Add(item); + + + FilterItem filter = Main.GetFilter(session); + if (filter != null) + { + var citem = new CheckMenuItem("Receive " + session.Name); + citem.Active = filter.Enabled; + citem.Toggled += (sender, e) => + { + filter.Enabled = !filter.Enabled; + Main.RedrawFilters(); + }; + context.Add(citem); + } + } + } context.Add(new SeparatorMenuItem()); @@ -101,6 +167,14 @@ namespace GridProxyGUI }; context.Add(item); + item = new MenuItem("Clear"); + item.Activated += (sender, e) => + { + Selection.UnselectAll(); + Messages.Clear(); + }; + context.Add(item); + context.ShowAll(); context.Popup(); }