WingMan

Subversion Repositories:
Compare Path: Rev
With Path: Rev
?path1? @ 13  →  ?path2? @ 14
File deleted
/trunk/WingMan/MouseKey/LocalKeyBindings.cs
File deleted
/trunk/WingMan/MouseKey/RemoteKeyBindings.cs
File deleted
/trunk/WingMan/MouseKey/KeyBindingsSynchronizerEventArgs.cs
File deleted
/trunk/WingMan/MouseKey/KeyBinding.cs
File deleted
/trunk/WingMan/MouseKey/KeyBindingsSynchronizer.cs
File deleted
/trunk/WingMan/MouseKey/KeyBindingExchange.cs
File deleted
/trunk/WingMan/MouseKey/ExecuteKeyBinding.cs
File deleted
/trunk/WingMan/MouseKey/KeyInterceptor.cs
File deleted
/trunk/WingMan/MouseKey/KeySimulator.cs
File deleted
/trunk/WingMan/MouseKey/KeyBindingMatchedEventArgs.cs
File deleted
/trunk/WingMan/MouseKey/KeyBindingsExchange.cs
File deleted
/trunk/WingMan/MouseKey/KeyBindingExecutingEventArgs.cs
File deleted
/trunk/WingMan/MouseKey/RemoteKeyBinding.cs
/trunk/WingMan/Bindings/ExecuteKeyBinding.cs
@@ -0,0 +1,23 @@
using System.Xml.Serialization;
 
namespace WingMan.Bindings
{
public class ExecuteKeyBinding
{
[XmlIgnore] public static readonly XmlSerializer XmlSerializer =
new XmlSerializer(typeof(ExecuteKeyBinding));
 
public ExecuteKeyBinding()
{
}
 
public ExecuteKeyBinding(string nick, string name)
{
Nick = nick;
Name = name;
}
 
public string Nick { get; set; }
public string Name { get; set; }
}
}
/trunk/WingMan/Bindings/KeyBinding.cs
@@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;
using System.Linq;
 
namespace WingMan.Bindings
{
public class KeyBinding : IEquatable<KeyBinding>
{
public KeyBinding()
{
}
 
public KeyBinding(string name, List<string> keys) : this()
{
Name = name;
Keys = keys;
}
 
public string DisplayName => $"{Name} ({string.Join(" + ", Keys.ToArray())})";
 
public string Name { get; set; } = string.Empty;
 
public List<string> Keys { get; set; } = new List<string>();
 
public bool Equals(KeyBinding other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
return string.Equals(Name, other.Name) && Keys.SequenceEqual(other.Keys);
}
 
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != GetType()) return false;
return Equals((KeyBinding) obj);
}
 
public override int GetHashCode()
{
unchecked
{
return ((Name != null ? Name.GetHashCode() : 0) * 397) ^ (Keys != null ? Keys.GetHashCode() : 0);
}
}
}
}
/trunk/WingMan/Bindings/KeyBindingExchange.cs
@@ -0,0 +1,25 @@
using System.Collections.Generic;
using System.Xml.Serialization;
 
namespace WingMan.Bindings
{
public class KeyBindingExchange
{
[XmlIgnore] public static readonly XmlSerializer XmlSerializer =
new XmlSerializer(typeof(KeyBindingExchange));
 
public KeyBindingExchange()
{
}
 
public KeyBindingExchange(string nick, List<KeyBinding> keyBindings)
{
Nick = nick;
KeyBindings = keyBindings;
}
 
public string Nick { get; set; }
 
public List<KeyBinding> KeyBindings { get; set; }
}
}
/trunk/WingMan/Bindings/KeyBindingExecutingEventArgs.cs
@@ -0,0 +1,16 @@
using System;
 
namespace WingMan.Bindings
{
public class KeyBindingExecutingEventArgs : EventArgs
{
public KeyBindingExecutingEventArgs(string nick, string name)
{
Nick = nick;
Name = name;
}
 
public string Nick { get; set; }
public string Name { get; set; }
}
}
/trunk/WingMan/Bindings/KeyBindingMatchedEventArgs.cs
@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
 
namespace WingMan.Bindings
{
public class KeyBindingMatchedEventArgs : EventArgs
{
public KeyBindingMatchedEventArgs(string nick, string name, List<string> keyCombo)
{
Nick = nick;
Name = name;
KeyCombo = keyCombo;
}
 
public string Nick { get; set; }
public string Name { get; set; }
public List<string> KeyCombo { get; set; }
}
}
/trunk/WingMan/Bindings/KeyBindingsExchange.cs
@@ -0,0 +1,9 @@
using System.Collections.Generic;
 
namespace WingMan.Bindings
{
public class KeyBindingsExchange
{
public List<KeyBindingExchange> ExchangeBindings { get; set; }
}
}
/trunk/WingMan/Bindings/KeyBindingsSynchronizer.cs
@@ -0,0 +1,103 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MQTTnet;
using WingMan.Communication;
 
namespace WingMan.Bindings
{
public class KeyBindingsSynchronizer : IDisposable
{
public delegate void MouseKeyBindingsSynchronized(object sender, KeyBindingsSynchronizerEventArgs e);
 
public KeyBindingsSynchronizer(LocalKeyBindings localKeyBindings, MqttCommunication mqttCommunication,
TaskScheduler taskScheduler, CancellationToken cancellationToken)
{
LocalKeyBindings = localKeyBindings;
MqttCommunication = mqttCommunication;
CancellationToken = cancellationToken;
TaskScheduler = taskScheduler;
 
SynchronizedMouseKeyBindings = new ConcurrentDictionary<string, List<KeyBinding>>();
 
MqttCommunication.OnMessageReceived += MqttCommunicationOnMessageReceived;
 
Task.Run(PeriodicSynchronize, CancellationToken);
}
 
private LocalKeyBindings LocalKeyBindings { get; }
 
private ConcurrentDictionary<string, List<KeyBinding>> SynchronizedMouseKeyBindings { get; }
 
private MqttCommunication MqttCommunication { get; }
 
private CancellationToken CancellationToken { get; }
private TaskScheduler TaskScheduler { get; }
 
public void Dispose()
{
MqttCommunication.OnMessageReceived -= MqttCommunicationOnMessageReceived;
}
 
public event MouseKeyBindingsSynchronized OnMouseKeyBindingsSynchronized;
 
private async void MqttCommunicationOnMessageReceived(object sender,
MqttApplicationMessageReceivedEventArgs e)
{
if (e.ApplicationMessage.Topic != "exchange")
return;
 
using (var memoryStream = new MemoryStream(e.ApplicationMessage.Payload))
{
memoryStream.Position = 0L;
 
var mouseKeyBindingsExchange =
(KeyBindingExchange) KeyBindingExchange.XmlSerializer.Deserialize(memoryStream);
 
// Do not add own bindings.
if (string.Equals(mouseKeyBindingsExchange.Nick, MqttCommunication.Nick))
return;
 
if (SynchronizedMouseKeyBindings.TryGetValue(mouseKeyBindingsExchange.Nick, out var mouseKeyBinding) &&
mouseKeyBinding.SequenceEqual(mouseKeyBindingsExchange.KeyBindings))
return;
 
await Task.Delay(0)
.ContinueWith(
_ => OnMouseKeyBindingsSynchronized?.Invoke(sender,
new KeyBindingsSynchronizerEventArgs(
mouseKeyBindingsExchange)),
CancellationToken, TaskContinuationOptions.None, TaskScheduler);
 
// Nick does not exist so the bindings will be added.
SynchronizedMouseKeyBindings.AddOrUpdate(mouseKeyBindingsExchange.Nick,
mouseKeyBindingsExchange.KeyBindings, (s, list) => mouseKeyBindingsExchange.KeyBindings);
}
}
 
private async Task PeriodicSynchronize()
{
do
{
await Task.Delay(1000, CancellationToken);
 
if (!MqttCommunication.Running)
continue;
 
using (var memoryStream = new MemoryStream())
{
KeyBindingExchange.XmlSerializer.Serialize(memoryStream,
new KeyBindingExchange(MqttCommunication.Nick, LocalKeyBindings.Bindings));
 
memoryStream.Position = 0L;
 
await MqttCommunication.Broadcast("exchange", memoryStream.ToArray());
}
} while (!CancellationToken.IsCancellationRequested);
}
}
}
/trunk/WingMan/Bindings/KeyBindingsSynchronizerEventArgs.cs
@@ -0,0 +1,14 @@
using System;
 
namespace WingMan.Bindings
{
public class KeyBindingsSynchronizerEventArgs : EventArgs
{
public KeyBindingsSynchronizerEventArgs(KeyBindingExchange keyExchangeBindings)
{
Bindings = keyExchangeBindings;
}
 
public KeyBindingExchange Bindings { get; set; }
}
}
/trunk/WingMan/Bindings/KeyInterceptor.cs
@@ -0,0 +1,155 @@
using System;
using System.Collections.Specialized;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
using System.Windows.Forms;
using Gma.System.MouseKeyHook;
using WingMan.Communication;
using WingMan.Utilities;
 
namespace WingMan.Bindings
{
public class KeyInterceptor : IDisposable
{
public delegate void MouseKeyBindingMatched(object sender, KeyBindingMatchedEventArgs args);
 
private volatile bool ProcessPipe;
 
public KeyInterceptor(RemoteKeyBindings remoteKeyBindings, MqttCommunication mqttCommunication,
TaskScheduler taskScheduler, CancellationToken cancellationToken)
{
DataFlowSemaphoreSlim = new SemaphoreSlim(1, 1);
 
RemoteKeyBindings = remoteKeyBindings;
RemoteKeyBindings.Bindings.CollectionChanged += OnRemoteKeyBindingsChanged;
 
MqttCommunication = mqttCommunication;
TaskScheduler = taskScheduler;
CancellationToken = cancellationToken;
 
MouseKeyGloalHook = Hook.GlobalEvents();
MouseKeyGloalHook.KeyUp += MouseKeyGloalHookOnKeyUp;
MouseKeyGloalHook.KeyDown += MouseKeyGloalHookOnKeyDown;
}
 
private BatchBlock<string> KeyComboBatchBlock { get; set; }
 
private ActionBlock<string[]> KeyComboActionBlock { get; set; }
 
private IDisposable KeyComboDataFlowLink { get; set; }
 
private SemaphoreSlim DataFlowSemaphoreSlim { get; }
 
private RemoteKeyBindings RemoteKeyBindings { get; }
private MqttCommunication MqttCommunication { get; }
private TaskScheduler TaskScheduler { get; }
private CancellationToken CancellationToken { get; }
 
private IKeyboardMouseEvents MouseKeyGloalHook { get; set; }
 
public void Dispose()
{
MouseKeyGloalHook.KeyUp -= MouseKeyGloalHookOnKeyUp;
MouseKeyGloalHook.KeyDown -= MouseKeyGloalHookOnKeyDown;
RemoteKeyBindings.Bindings.CollectionChanged -= OnRemoteKeyBindingsChanged;
 
KeyComboDataFlowLink?.Dispose();
KeyComboDataFlowLink = null;
 
MouseKeyGloalHook?.Dispose();
MouseKeyGloalHook = null;
}
 
private async void OnRemoteKeyBindingsChanged(object sender, NotifyCollectionChangedEventArgs e)
{
await DataFlowSemaphoreSlim.WaitAsync(CancellationToken);
 
try
{
// Break the link and dispose it.
KeyComboDataFlowLink?.Dispose();
KeyComboDataFlowLink = null;
 
// Create a sliding window of size equal to the longest key combination.
var maxKeyComboLength = RemoteKeyBindings.Bindings.Max(binding => binding.Keys.Count);
 
KeyComboBatchBlock =
new BatchBlock<string>(maxKeyComboLength);
KeyComboActionBlock = new ActionBlock<string[]>(ProcessKeyCombos,
new ExecutionDataflowBlockOptions {CancellationToken = CancellationToken});
KeyComboDataFlowLink = KeyComboBatchBlock.LinkTo(KeyComboActionBlock);
}
finally
{
DataFlowSemaphoreSlim.Release();
}
}
 
private async Task ProcessKeyCombos(string[] keys)
{
await DataFlowSemaphoreSlim.WaitAsync(CancellationToken);
 
try
{
if (!ProcessPipe)
return;
 
foreach (var binding in RemoteKeyBindings.Bindings)
{
if (!keys.SubsetEquals(binding.Keys))
continue;
 
// Raise the match event.
await Task.Delay(0, CancellationToken)
.ContinueWith(
_ => OnMouseKeyBindingMatched?.Invoke(this,
new KeyBindingMatchedEventArgs(binding.Nick, binding.Name, binding.Keys)),
CancellationToken,
TaskContinuationOptions.None, TaskScheduler);
 
using (var memoryStream = new MemoryStream())
{
ExecuteKeyBinding.XmlSerializer.Serialize(memoryStream,
new ExecuteKeyBinding(binding.Nick, binding.Name));
 
memoryStream.Position = 0L;
 
await MqttCommunication.Broadcast("execute", memoryStream.ToArray());
}
}
}
finally
{
DataFlowSemaphoreSlim.Release();
}
}
 
public event MouseKeyBindingMatched OnMouseKeyBindingMatched;
 
private async void MouseKeyGloalHookOnKeyDown(object sender, KeyEventArgs e)
{
ProcessPipe = true;
 
if (!KeyConversion.KeysToString.TryGetValue((byte) e.KeyCode, out var key))
return;
 
await DataFlowSemaphoreSlim.WaitAsync(CancellationToken);
try
{
if (KeyComboBatchBlock != null) await KeyComboBatchBlock.SendAsync(key, CancellationToken);
}
finally
{
DataFlowSemaphoreSlim.Release();
}
}
 
private void MouseKeyGloalHookOnKeyUp(object sender, KeyEventArgs e)
{
ProcessPipe = false;
}
}
}
/trunk/WingMan/Bindings/KeySimulator.cs
@@ -0,0 +1,92 @@
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using MQTTnet;
using SimWinInput;
using WingMan.Communication;
using WingMan.Utilities;
 
namespace WingMan.Bindings
{
public class KeySimulator : IDisposable
{
public delegate void MouseKeyBindingExecuting(object sender, KeyBindingExecutingEventArgs args);
 
public KeySimulator(LocalKeyBindings localLocalKeyBindings, MqttCommunication mqttCommunication,
TaskScheduler formTaskScheduler, CancellationToken cancellationToken)
{
LocalLocalKeyBindings = localLocalKeyBindings;
MqttCommunication = mqttCommunication;
TaskScheduler = formTaskScheduler;
CancellationToken = cancellationToken;
 
MqttCommunication.OnMessageReceived += OnMqttMessageReceived;
}
 
private MqttCommunication MqttCommunication { get; }
private TaskScheduler TaskScheduler { get; }
private CancellationToken CancellationToken { get; }
private LocalKeyBindings LocalLocalKeyBindings { get; }
 
public void Dispose()
{
MqttCommunication.OnMessageReceived -= OnMqttMessageReceived;
}
 
public event MouseKeyBindingExecuting OnMouseKeyBindingExecuting;
 
private async void OnMqttMessageReceived(object sender, MqttApplicationMessageReceivedEventArgs e)
{
if (e.ApplicationMessage.Topic != "execute")
return;
 
using (var memoryStream = new MemoryStream(e.ApplicationMessage.Payload))
{
var executeMouseKeyBinding =
(ExecuteKeyBinding) ExecuteKeyBinding.XmlSerializer.Deserialize(memoryStream);
 
// Do not process own mouse key bindings.
if (!string.Equals(executeMouseKeyBinding.Nick, MqttCommunication.Nick, StringComparison.Ordinal))
return;
 
await Task.Delay(0, CancellationToken)
.ContinueWith(
_ => OnMouseKeyBindingExecuting?.Invoke(sender,
new KeyBindingExecutingEventArgs(executeMouseKeyBinding.Nick,
executeMouseKeyBinding.Name)),
CancellationToken,
TaskContinuationOptions.None, TaskScheduler);
 
Simulate(executeMouseKeyBinding);
}
}
 
private void Simulate(ExecuteKeyBinding executeBinding)
{
foreach (var localBinding in LocalLocalKeyBindings.Bindings)
{
if (!string.Equals(localBinding.Name, executeBinding.Name, StringComparison.Ordinal))
continue;
 
// Press
foreach (var key in localBinding.Keys)
{
if (!KeyConversion.StringToKeys.TryGetValue(key, out var pressKey))
continue;
 
SimKeyboard.KeyDown(pressKey);
}
 
// Depress
foreach (var key in localBinding.Keys)
{
if (!KeyConversion.StringToKeys.TryGetValue(key, out var pressKey))
continue;
 
SimKeyboard.KeyUp(pressKey);
}
}
}
}
}
/trunk/WingMan/Bindings/LocalKeyBindings.cs
@@ -0,0 +1,21 @@
using System.Collections.Generic;
using System.Xml.Serialization;
 
namespace WingMan.Bindings
{
public class LocalKeyBindings
{
[XmlIgnore] public static readonly XmlSerializer XmlSerializer = new XmlSerializer(typeof(LocalKeyBindings));
 
public LocalKeyBindings()
{
}
 
public LocalKeyBindings(List<KeyBinding> bindings) : this()
{
Bindings = bindings;
}
 
public List<KeyBinding> Bindings { get; set; }
}
}
/trunk/WingMan/Bindings/RemoteKeyBinding.cs
@@ -0,0 +1,24 @@
using System.Collections.Generic;
 
namespace WingMan.Bindings
{
public class RemoteKeyBinding
{
public RemoteKeyBinding()
{
}
 
public RemoteKeyBinding(string nick, string name, List<string> mouseKeyCombo)
{
Nick = nick;
Name = name;
Keys = mouseKeyCombo;
}
 
public string Nick { get; set; }
 
public string Name { get; set; }
 
public List<string> Keys { get; set; }
}
}
/trunk/WingMan/Bindings/RemoteKeyBindings.cs
@@ -0,0 +1,22 @@
using System.Collections.ObjectModel;
using System.Xml.Serialization;
 
namespace WingMan.Bindings
{
public class RemoteKeyBindings
{
[XmlIgnore] public static readonly XmlSerializer XmlSerializer =
new XmlSerializer(typeof(RemoteKeyBindings));
 
public RemoteKeyBindings()
{
}
 
public RemoteKeyBindings(ObservableCollection<RemoteKeyBinding> bindings)
{
Bindings = bindings;
}
 
public ObservableCollection<RemoteKeyBinding> Bindings { get; set; }
}
}
/trunk/WingMan/Communication/MqttCommunication.cs
@@ -1,7 +1,6 @@
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using MQTTnet;
@@ -348,7 +347,7 @@
switch (Type)
{
case MqttCommunicationType.Client:
await Client.PublishAsync(new []
await Client.PublishAsync(new[]
{
new MqttApplicationMessage
{
/trunk/WingMan/Program.cs
@@ -16,4 +16,4 @@
Application.Run(new WingManForm());
}
}
}
}
/trunk/WingMan/Utilities/AES.cs
@@ -1,5 +1,4 @@
using System;
using System.IO;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
/trunk/WingMan/Utilities/Extensions.cs
@@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Linq;
 
namespace WingMan.Utilities
{
public static class Extensions
{
/// <summary>
/// Sequentially removes all the elements from the first sequence that are in the second sequence.
/// </summary>
/// <typeparam name="T">the type o the collection</typeparam>
/// <param name="o">the first sequence to remove from</param>
/// <param name="p">the second sequence to remove</param>
/// <returns>the first sequence excluding the second sequence</returns>
public static IEnumerable<T> SequenceExcept<T>(this IEnumerable<T> a, IEnumerable<T> b) where T : IEquatable<T>
{
using (var ea = a.GetEnumerator())
{
using (var eb = b.GetEnumerator())
{
while (ea.MoveNext())
{
if (eb.MoveNext() && ea.Current.Equals(eb.Current))
continue;
yield return ea.Current;
}
}
}
}
 
/// <summary>
/// Determines whether a sequence is contained within another sequence.
/// </summary>
/// <returns>true if and only if the first set is contained in the second set</returns>
/// <param name="a">The set to check</param>
/// <param name="b">The set to check against</param>
/// <typeparam name="T">the set type</typeparam>
public static bool SubsetEquals<T>(this IEnumerable<T> a, IEnumerable<T> b) where T : IEquatable<T>
{
return !a.OrderBy(s => s).SequenceExcept(b.OrderBy(s => s)).Any();
}
}
}
/trunk/WingMan/Utilities/KeyConversion.cs
@@ -1,26 +1,9 @@
using System.Collections.Generic;
using System.Windows.Forms;
 
namespace WingMan
namespace WingMan.Utilities
{
public static class KeyConversion
{
public static readonly Dictionary<MouseButtons, string> MouseButtonsToString =
new Dictionary<MouseButtons, string>
{
{MouseButtons.Left, "Left Mouse Button"},
{MouseButtons.Middle, "Middle Mouse Button"},
{MouseButtons.Right, "Right Mouse Button"}
};
 
public static readonly Dictionary<string, MouseButtons> StringToMouseButtons =
new Dictionary<string, MouseButtons>
{
{"Left Mouse Button", MouseButtons.Left},
{"Middle Mouse Button", MouseButtons.Middle},
{"Right Mouse Button", MouseButtons.Right}
};
 
public static readonly Dictionary<string, byte> StringToKeys = new Dictionary<string, byte>
{
{"None", 0},
/trunk/WingMan/WingMan.csproj
@@ -74,23 +74,24 @@
<Compile Include="Communication\MqttAuthenticationFailureEventArgs.cs" />
<Compile Include="Lobby\LobbyMessageReceivedEventArgs.cs" />
<Compile Include="Lobby\LobbyMessageSynchronizer.cs" />
<Compile Include="MouseKey\ExecuteKeyBinding.cs" />
<Compile Include="MouseKey\KeyBindingExchange.cs" />
<Compile Include="MouseKey\KeyBindingExecutingEventArgs.cs" />
<Compile Include="MouseKey\KeyBindingMatchedEventArgs.cs" />
<Compile Include="MouseKey\KeyBindingsSynchronizerEventArgs.cs" />
<Compile Include="MouseKey\KeyBindingsSynchronizer.cs" />
<Compile Include="Bindings\ExecuteKeyBinding.cs" />
<Compile Include="Bindings\KeyBindingExchange.cs" />
<Compile Include="Bindings\KeyBindingExecutingEventArgs.cs" />
<Compile Include="Bindings\KeyBindingMatchedEventArgs.cs" />
<Compile Include="Bindings\KeyBindingsSynchronizerEventArgs.cs" />
<Compile Include="Bindings\KeyBindingsSynchronizer.cs" />
<Compile Include="Communication\MqttCommunication.cs" />
<Compile Include="MouseKey\KeyBinding.cs" />
<Compile Include="MouseKey\LocalKeyBindings.cs" />
<Compile Include="MouseKey\KeyBindingsExchange.cs" />
<Compile Include="Bindings\KeyBinding.cs" />
<Compile Include="Bindings\LocalKeyBindings.cs" />
<Compile Include="Bindings\KeyBindingsExchange.cs" />
<Compile Include="Lobby\LobbyMessage.cs" />
<Compile Include="Communication\MqttCommunicationType.cs" />
<Compile Include="MouseKey\KeyInterceptor.cs" />
<Compile Include="MouseKey\KeySimulator.cs" />
<Compile Include="MouseKey\RemoteKeyBinding.cs" />
<Compile Include="MouseKey\RemoteKeyBindings.cs" />
<Compile Include="Bindings\KeyInterceptor.cs" />
<Compile Include="Bindings\KeySimulator.cs" />
<Compile Include="Bindings\RemoteKeyBinding.cs" />
<Compile Include="Bindings\RemoteKeyBindings.cs" />
<Compile Include="Utilities\AES.cs" />
<Compile Include="Utilities\Extensions.cs" />
<Compile Include="Utilities\KeyConversion.cs" />
<Compile Include="WingManForm.cs">
<SubType>Form</SubType>
/trunk/WingMan/WingManForm.Designer.cs
@@ -420,6 +420,7 @@
this.ActivityTextBox.Location = new System.Drawing.Point(8, 16);
this.ActivityTextBox.Multiline = true;
this.ActivityTextBox.Name = "ActivityTextBox";
this.ActivityTextBox.ReadOnly = true;
this.ActivityTextBox.Size = new System.Drawing.Size(496, 152);
this.ActivityTextBox.TabIndex = 4;
//
/trunk/WingMan/WingManForm.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Drawing;
using System.IO;
using System.Linq;
@@ -10,9 +11,9 @@
using Gma.System.MouseKeyHook;
using MQTTnet.Extensions.ManagedClient;
using MQTTnet.Server;
using WingMan.Bindings;
using WingMan.Communication;
using WingMan.Lobby;
using WingMan.MouseKey;
using WingMan.Properties;
using WingMan.Utilities;
 
@@ -39,7 +40,7 @@
MqttCommunication.OnServerClientDisconnected += OnMqttServerClientDisconnected;
 
LocalKeyBindings = new LocalKeyBindings(new List<KeyBinding>());
RemoteKeyBindings = new RemoteKeyBindings(new List<RemoteKeyBinding>());
RemoteKeyBindings = new RemoteKeyBindings(new ObservableCollection<RemoteKeyBinding>());
 
LocalListBoxBindingSource = new BindingSource
{
@@ -232,7 +233,7 @@
if (exchangeBindings == null)
return;
 
var replaceMouseBindings = new List<RemoteKeyBinding>();
var replaceMouseBindings = new ObservableCollection<RemoteKeyBinding>();
foreach (var remoteBinding in RemoteKeyBindings.Bindings)
{
if (!exchangeBindings.Any(binding =>
@@ -448,7 +449,7 @@
OverlayPanel.Invalidate();
}
 
private void LocalMouseKeyHookOnKeyUp(object sender, KeyEventArgs e)
private async void LocalMouseKeyHookOnKeyUp(object sender, KeyEventArgs e)
{
LocalKeyBindings.Bindings.Add(new KeyBinding(LocalNameTextBox.Text, MouseKeyCombo));
 
@@ -462,7 +463,7 @@
LocalNameTextBox.Text = string.Empty;
HideOverlayPanel();
 
//await SaveLocalMouseKeyBindings();
await SaveLocalMouseKeyBindings();
}
 
private void HideOverlayPanel()
@@ -486,7 +487,7 @@
LocalNameTextBox.BackColor = Color.Empty;
}
 
private void LocalBindingsRemoveButtonClick(object sender, EventArgs e)
private async void LocalBindingsRemoveButtonClick(object sender, EventArgs e)
{
var helmBinding = (KeyBinding) LocalBindingsListBox.SelectedItem;
if (helmBinding == null)
@@ -495,7 +496,7 @@
LocalKeyBindings.Bindings.Remove(helmBinding);
LocalListBoxBindingSource.ResetBindings(false);
 
// await SaveLocalMouseKeyBindings();
await SaveLocalMouseKeyBindings();
}
 
private async void LobbySayButtonClick(object sender, EventArgs e)
@@ -510,11 +511,11 @@
UpdateRemoteItems();
}
 
private void WingManFormOnLoad(object sender, EventArgs e)
private async void WingManFormOnLoad(object sender, EventArgs e)
{
// await LoadLocalMouseKeyBindings();
await LoadLocalMouseKeyBindings();
 
// await LoadRemoteMouseKeyBindings();
await LoadRemoteMouseKeyBindings();
}
 
private void RemoteBindingsBindButtonClicked(object sender, EventArgs e)
@@ -566,7 +567,7 @@
MouseKeyCombo.Add(key);
}
 
private void RemoteMouseKeyHookOnKeyUp(object sender, KeyEventArgs e)
private async void RemoteMouseKeyHookOnKeyUp(object sender, KeyEventArgs e)
{
RemoteKeyBindings.Bindings.Add(new RemoteKeyBinding(RemoteBindingsComboBox.Text,
(string) RemoteBindingsListBox.SelectedItem, MouseKeyCombo));
@@ -579,7 +580,7 @@
RemoteBindingsBindToBox.Text = string.Join(" + ", MouseKeyCombo);
HideOverlayPanel();
 
// await SaveRemoteMouseKeyBindings();
await SaveRemoteMouseKeyBindings();
}
 
private void RemoteBindingsListBoxSelectedValueChanged(object sender, EventArgs e)
@@ -590,9 +591,13 @@
if (string.IsNullOrEmpty(name))
return;
 
var nick = RemoteBindingsComboBox.Text;
if (string.IsNullOrEmpty(nick))
return;
 
foreach (var binding in RemoteKeyBindings.Bindings)
{
if (!string.Equals(binding.Name, name))
if (!string.Equals(binding.Nick, nick) || !string.Equals(binding.Name, name))
continue;
 
RemoteBindingsBindToBox.Text = string.Join(" + ", binding.Keys);