Persist filters. Add context menu options
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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<string> LoginServers = new List<string>();
|
||||
|
||||
ConcurrentDictionary<string, FilterItem> UDPFilterItems = new ConcurrentDictionary<string, FilterItem>();
|
||||
ConcurrentDictionary<string, FilterItem> CapFilterItems = new ConcurrentDictionary<string, FilterItem>();
|
||||
ListStore udpStore = new ListStore(typeof(FilterItem));
|
||||
ListStore capStore = new ListStore(typeof(FilterItem));
|
||||
FilterScroller udpScroller, capScroller;
|
||||
|
||||
void LoadFromOSD(ConcurrentDictionary<string, FilterItem> 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<string> keys = new List<string>(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<string> keys = new List<string>(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;
|
||||
|
||||
|
||||
@@ -11,10 +11,6 @@ using System.Text.RegularExpressions;
|
||||
public partial class MainWindow : Gtk.Window
|
||||
{
|
||||
ProxyManager proxy = null;
|
||||
ConcurrentDictionary<string, FilterItem> UDPFilterItems = new ConcurrentDictionary<string, FilterItem>();
|
||||
ConcurrentDictionary<string, FilterItem> CapFilterItems = new ConcurrentDictionary<string, FilterItem>();
|
||||
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<Widget>(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<string> keys = new List<string>(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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user