using System; using System.Collections.Generic; using System.Linq; using System.Windows.Input; using NetLimiter.Service; using tsf_3074.Data; namespace tsf_3074 { public static class Tsf { private const string Prefix = "tsf"; // thirty-seventy-four private static NLClient _client; private static NLClient GetClient() { if (_client != null) return _client; _client = new NLClient(); _client.Connect(); return _client; } private static string GetFilterNameFor(string portName, bool upload = false) { return upload ? $"{Prefix}_{portName}_ul" : $"{Prefix}_{portName}"; } private static TsfFilter CreateFilter(string portName, ushort portStart, ushort portEnd, bool upload = false, uint fs = 0, uint vk = 0) { var cli = GetClient(); var name = GetFilterNameFor(portName, upload); var filter = cli.Filters.FirstOrDefault(f => f.Name == name) ?? cli.AddFilter(new Filter(name) { Functions = { new FFPathEqual(Config.Instance.Destiny2Path), new FFRemotePortInRange(new PortRangeFilterValue(portStart, portEnd)) } }); var hotkey = Config.Instance.Hotkeys[name]; if (hotkey != null) { vk = hotkey.vk; fs = hotkey.fs; } return new TsfFilter(name, filter, cli, upload, 1, fs, vk); } private static TsfFilter CreateFilterFullGame(uint fs, uint vk) { var cli = GetClient(); var name = GetFilterNameFor("fg"); var filter = cli.Filters.FirstOrDefault(f => f.Name == name) ?? cli.AddFilter(new Filter(name) { Functions = { new FFPathEqual(Config.Instance.Destiny2Path) } }); var hotkey = Config.Instance.Hotkeys[name]; if (hotkey != null) { vk = hotkey.vk; fs = hotkey.fs; } return new TsfFilter(name, filter, cli, false, 811, fs, vk); } public static readonly TsfFilter F3074; public static readonly TsfFilter F3074UL; public static readonly TsfFilter F7500; public static readonly TsfFilter F27K; public static readonly TsfFilter F30K; public static readonly TsfFilter FFullGame; static Tsf() { F3074 = CreateFilter("3074", 3074, 3074, false, VirtualKey.ModCtrl, VirtualKey.VkG); F3074UL = CreateFilter("3074", 3074, 3074, true, VirtualKey.ModCtrl, VirtualKey.VkH); F7500 = CreateFilter("7500", 7500, 7509, false, VirtualKey.ModCtrl, VirtualKey.VkT); F27K = CreateFilter("27k", 27015, 27200, false, VirtualKey.ModAlt, VirtualKey.VkN); F30K = CreateFilter("30k", 30000, 30009, false, VirtualKey.ModAlt, VirtualKey.VkB); FFullGame = CreateFilterFullGame(VirtualKey.ModCtrl, VirtualKey.VkJ); } } public class TsfFilter { private readonly string _name; private readonly Filter _filter; private readonly NLClient _client; private readonly bool _upload; private readonly uint _limitSize; // the limit rate, normally is 1, only FG is 800 or 811 private uint _fs; private uint _vk; public string Name => _name; public uint FS => _fs; public uint VK => _vk; private Rule _rule; /** * Invoked every time the IsEnable is changed. (Maybe not actually changed, like from false to false.) */ public event OnEvent OnStateChanged = delegate { }; public static readonly List AllFilters = new List(); public TsfFilter(string name, Filter filter, NLClient client, bool upload, uint limitSize = 1, uint fs = 0, uint vk = 0) { _name = name; _filter = filter; _client = client; _upload = upload; _limitSize = limitSize; _fs = fs; _vk = vk; InitLimitRule(); AllFilters.Add(this); } ~TsfFilter() { AllFilters.Remove(this); } /** * Set the keybindings. Need to reload the hotkey manager manually! */ public void SetHotkey(uint vk, uint fs) { _vk = vk; _fs = fs; } /** * Register the hotkey to the HotkeyManager. */ internal void RegisterHotkey(HotkeyManager manager) { if (_vk != 0) { Console.WriteLine( $"Registering Hotkey for {_name} {VirtualKey.GetModifierName(_fs)} + {KeyInterop.KeyFromVirtualKey((int)_vk)}"); manager.RegisterHotkey(_fs, _vk, () => { Toggle(); Console.WriteLine($"Updated {_name} to {GetState()}"); }); } } private void InitLimitRule() { if (_rule != null) return; var dir = _upload ? RuleDir.Out : RuleDir.In; _rule = _client.Rules.FirstOrDefault(r => r.FilterId == _filter.Id && r.Dir == dir) ?? _client.AddRule(_filter.Id, new LimitRule(dir, _limitSize) { IsEnabled = false }); } public void Toggle() { _rule.IsEnabled = !_rule.IsEnabled; _rule = _client.UpdateRule(_rule).Rule; OnStateChanged.Invoke(); } public void Set(bool value) { _rule.IsEnabled = value; _rule = _client.UpdateRule(_rule).Rule; OnStateChanged.Invoke(); } public bool IsEnabled() { return _rule?.IsEnabled ?? false; } public string GetState() { return IsEnabled() ? "On" : "Off"; } } }