diff --git a/LCUSharp/LCUSharp.csproj b/LCUSharp/LCUSharp.csproj
index b6b438e..1a97dd7 100644
--- a/LCUSharp/LCUSharp.csproj
+++ b/LCUSharp/LCUSharp.csproj
@@ -2,8 +2,8 @@
netcoreapp3.1
- 1.3.15.0
- 1.3.15.21188
+ 1.4.0.0
+ 1.4.0.21190
diff --git a/LeagueBroadcast.Common/LeagueBroadcast.Common.csproj b/LeagueBroadcast.Common/LeagueBroadcast.Common.csproj
index 05c59cb..2225bd9 100644
--- a/LeagueBroadcast.Common/LeagueBroadcast.Common.csproj
+++ b/LeagueBroadcast.Common/LeagueBroadcast.Common.csproj
@@ -2,8 +2,8 @@
netcoreapp3.1
- 1.3.29.0
- 1.3.29.21188
+ 1.4.0.0
+ 1.4.0.21190
latest
diff --git a/LeagueBroadcast.Farsight/LeagueBroadcast.Farsight.csproj b/LeagueBroadcast.Farsight/LeagueBroadcast.Farsight.csproj
index aa76e63..4cdc683 100644
--- a/LeagueBroadcast.Farsight/LeagueBroadcast.Farsight.csproj
+++ b/LeagueBroadcast.Farsight/LeagueBroadcast.Farsight.csproj
@@ -3,8 +3,8 @@
netcoreapp3.1
latest
- 1.3.45.0
- 1.3.45.21188
+ 1.4.0.0
+ 1.4.0.21190
Library
diff --git a/LeagueBroadcast.Trinket/LeagueBroadcast.Trinket.csproj b/LeagueBroadcast.Trinket/LeagueBroadcast.Trinket.csproj
index c3f347b..9e1a2a8 100644
--- a/LeagueBroadcast.Trinket/LeagueBroadcast.Trinket.csproj
+++ b/LeagueBroadcast.Trinket/LeagueBroadcast.Trinket.csproj
@@ -2,8 +2,8 @@
netcoreapp3.1
- 1.3.17.0
- 1.3.17.21188
+ 1.4.0.0
+ 1.4.0.21190
Library
diff --git a/LeagueBroadcast.Update/LeagueBroadcast.Update.csproj b/LeagueBroadcast.Update/LeagueBroadcast.Update.csproj
index 92c503f..97df9bf 100644
--- a/LeagueBroadcast.Update/LeagueBroadcast.Update.csproj
+++ b/LeagueBroadcast.Update/LeagueBroadcast.Update.csproj
@@ -2,8 +2,8 @@
netcoreapp3.1
- 1.3.29.0
- 1.3.29.21188
+ 1.4.0.0
+ 1.4.0.21190
diff --git a/LeagueBroadcast/LeagueBroadcast.csproj b/LeagueBroadcast/LeagueBroadcast.csproj
index 872242d..6cb030b 100644
--- a/LeagueBroadcast/LeagueBroadcast.csproj
+++ b/LeagueBroadcast/LeagueBroadcast.csproj
@@ -15,8 +15,8 @@
https://github.com/floh22/LeagueBroadcast
Git
BE_icon.png
- 1.3.234.0
- 1.3.234.21189
+ 1.4.0.0
+ 1.4.0.21189
diff --git a/LeagueBroadcast/MVVM/Controls/HotKeyTextBox.cs b/LeagueBroadcast/MVVM/Controls/HotKeyTextBox.cs
new file mode 100644
index 0000000..dad5ae8
--- /dev/null
+++ b/LeagueBroadcast/MVVM/Controls/HotKeyTextBox.cs
@@ -0,0 +1,104 @@
+using LeagueBroadcast.MVVM.Models;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+
+namespace LeagueBroadcast.MVVM.Controls
+{
+ //Modified from https://github.com/Tyrrrz/LightBulb/blob/master/LightBulb/Views/Controls/HotKeyTextBox.cs
+ public class HotKeyTextBox : TextBox
+ {
+ public static readonly DependencyProperty HotKeyProperty =
+ DependencyProperty.Register(nameof(HotKey), typeof(HotKey), typeof(HotKeyTextBox),
+ new FrameworkPropertyMetadata(default(HotKey), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, HotKeyChanged));
+
+ private static void HotKeyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
+ {
+ if (sender is HotKeyTextBox control)
+ {
+ control.Text = control.HotKey.ToString();
+ }
+ }
+
+ public HotKey HotKey
+ {
+ get => (HotKey)GetValue(HotKeyProperty);
+ set => SetValue(HotKeyProperty, value);
+ }
+
+ public HotKeyTextBox()
+ {
+ IsReadOnly = true;
+ IsReadOnlyCaretVisible = false;
+ IsUndoEnabled = false;
+
+ if (ContextMenu is not null)
+ ContextMenu.Visibility = Visibility.Collapsed;
+
+ Text = HotKey.ToString();
+ }
+
+ private static bool HasKeyChar(Key key) =>
+ // A - Z
+ key >= Key.A && key <= Key.Z ||
+ // 0 - 9
+ key >= Key.D0 && key <= Key.D9 ||
+ // Numpad 0 - 9
+ key >= Key.NumPad0 && key <= Key.NumPad9 ||
+ // The rest
+ key == Key.OemQuestion || key == Key.OemQuotes || key == Key.OemPlus || key == Key.OemOpenBrackets || key == Key.OemCloseBrackets ||
+ key == Key.OemMinus || key == Key.DeadCharProcessed || key == Key.Oem1 || key == Key.Oem5 || key == Key.Oem7 || key == Key.OemPeriod || key == Key.OemComma || key == Key.Add ||
+ key == Key.Divide || key == Key.Multiply || key == Key.Subtract || key == Key.Oem102 || key == Key.Decimal;
+
+ protected override void OnPreviewKeyDown(KeyEventArgs e)
+ {
+ e.Handled = true;
+
+ // Get modifiers and key data
+ var modifiers = Keyboard.Modifiers;
+ var key = e.Key;
+
+ // If nothing was pressed - return
+ if (key == Key.None)
+ return;
+
+ // If Alt is used as modifier - the key needs to be extracted from SystemKey
+ if (key == Key.System)
+ key = e.SystemKey;
+
+ // If Delete/Backspace/Escape is pressed without modifiers - clear current value and return
+ if ((key == Key.Delete || key == Key.Back || key == Key.Escape) && modifiers == ModifierKeys.None)
+ {
+ HotKey = HotKey.None;
+ return;
+ }
+
+ // If no actual key was pressed - return
+ if (key == Key.LeftCtrl ||
+ key == Key.RightCtrl ||
+ key == Key.LeftAlt ||
+ key == Key.RightAlt ||
+ key == Key.LeftShift ||
+ key == Key.RightShift ||
+ key == Key.LWin ||
+ key == Key.RWin ||
+ key == Key.Clear ||
+ key == Key.OemClear ||
+ key == Key.Apps)
+ {
+ return;
+ }
+
+ // If Enter/Space/Tab is pressed without modifiers - return
+ if ((key == Key.Enter || key == Key.Space || key == Key.Tab) && modifiers == ModifierKeys.None)
+ return;
+
+ // If key has a character and pressed without modifiers or only with Shift - return
+ if (HasKeyChar(key) && (modifiers == ModifierKeys.None || modifiers == ModifierKeys.Shift))
+ return;
+
+ // Set value
+ HotKey = new HotKey(key, modifiers);
+ }
+ }
+}
diff --git a/LeagueBroadcast/MVVM/Models/HotKey.cs b/LeagueBroadcast/MVVM/Models/HotKey.cs
new file mode 100644
index 0000000..1ceb2ed
--- /dev/null
+++ b/LeagueBroadcast/MVVM/Models/HotKey.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Text;
+using System.Windows.Input;
+
+namespace LeagueBroadcast.MVVM.Models
+{
+ //https://github.com/Tyrrrz/LightBulb/blob/master/LightBulb/Models/HotKey.cs
+ public readonly partial struct HotKey
+ {
+ public Key Key { get; }
+
+ public ModifierKeys Modifiers { get; }
+
+ public HotKey(Key key, ModifierKeys modifiers = ModifierKeys.None)
+ {
+ Key = key;
+ Modifiers = modifiers;
+ }
+
+ public override string ToString()
+ {
+ if (Key == Key.None && Modifiers == ModifierKeys.None)
+ return "< None >";
+
+ var buffer = new StringBuilder();
+
+ if (Modifiers.HasFlag(ModifierKeys.Control))
+ buffer.Append("Ctrl + ");
+ if (Modifiers.HasFlag(ModifierKeys.Shift))
+ buffer.Append("Shift + ");
+ if (Modifiers.HasFlag(ModifierKeys.Alt))
+ buffer.Append("Alt + ");
+ if (Modifiers.HasFlag(ModifierKeys.Windows))
+ buffer.Append("Win + ");
+
+ buffer.Append(Key);
+
+ return buffer.ToString();
+ }
+ }
+
+ public partial struct HotKey
+ {
+ public static HotKey None { get; } = new();
+ }
+
+ public partial struct HotKey : IEquatable
+ {
+ public bool Equals(HotKey other) => Key == other.Key && Modifiers == other.Modifiers;
+
+ public override bool Equals(object? obj) => obj is HotKey other && Equals(other);
+
+ public override int GetHashCode() => HashCode.Combine(Key, Modifiers);
+
+ public static bool operator ==(HotKey a, HotKey b) => a.Equals(b);
+
+ public static bool operator !=(HotKey a, HotKey b) => !(a == b);
+ }
+}
diff --git a/LeagueBroadcast/OperatingSystem/GlobalHotKey.cs b/LeagueBroadcast/OperatingSystem/GlobalHotKey.cs
new file mode 100644
index 0000000..4a1ea2b
--- /dev/null
+++ b/LeagueBroadcast/OperatingSystem/GlobalHotKey.cs
@@ -0,0 +1,166 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Windows.Input;
+
+namespace LeagueBroadcast.OperatingSystem
+{
+ //Modified from https://stackoverflow.com/a/65412682
+ public class GlobalHotKey : IDisposable
+ {
+ ///
+ /// Registers a global hotkey
+ ///
+ /// e.g. Alt + Shift + Control + Win + S
+ /// Action to be called when hotkey is pressed
+ /// true, if registration succeeded, otherwise false
+ public static int RegisterHotKey(string aKeyGestureString, Action aAction)
+ {
+ var c = new KeyGestureConverter();
+ KeyGesture aKeyGesture = (KeyGesture)c.ConvertFrom(aKeyGestureString);
+ return RegisterHotKey(aKeyGesture.Modifiers, aKeyGesture.Key, aAction);
+ }
+
+ public static int RegisterHotKey(ModifierKeys aModifier, Key aKey, Action aAction)
+ {
+ if (aModifier == ModifierKeys.None)
+ {
+ throw new ArgumentException("Modifier must not be ModifierKeys.None");
+ }
+ if (aAction is null)
+ {
+ throw new ArgumentNullException(nameof(aAction));
+ }
+
+ System.Windows.Forms.Keys aVirtualKeyCode = (System.Windows.Forms.Keys)KeyInterop.VirtualKeyFromKey(aKey);
+ currentID = currentID + 1;
+ bool aRegistered = RegisterHotKey(window.Handle, currentID,
+ (uint)aModifier | MOD_NOREPEAT,
+ (uint)aVirtualKeyCode);
+
+ if (aRegistered)
+ {
+ registeredHotKeys.Add(new HotKeyWithAction(aModifier, aKey, aAction));
+ return currentID;
+ }
+
+ return -1;
+ }
+
+ public static void UnregisterHotKey(int ID)
+ {
+ UnregisterHotKey(window.Handle, ID);
+ }
+
+ public void Dispose()
+ {
+ // unregister all the registered hot keys.
+ for (int i = currentID; i > 0; i--)
+ {
+ UnregisterHotKey(window.Handle, i);
+ }
+
+ // dispose the inner native window.
+ window.Dispose();
+ }
+
+ static GlobalHotKey()
+ {
+ window.KeyPressed += (s, e) =>
+ {
+ registeredHotKeys.ForEach(x =>
+ {
+ if (e.Modifier == x.Modifier && e.Key == x.Key)
+ {
+ x.Action();
+ }
+ });
+ };
+ }
+
+ private static readonly InvisibleWindowForMessages window = new InvisibleWindowForMessages();
+ private static int currentID;
+ private static uint MOD_NOREPEAT = 0x4000;
+ private static List registeredHotKeys = new List();
+
+ private class HotKeyWithAction
+ {
+
+ public HotKeyWithAction(ModifierKeys modifier, Key key, Action action)
+ {
+ Modifier = modifier;
+ Key = key;
+ Action = action;
+ }
+
+ public ModifierKeys Modifier { get; }
+ public Key Key { get; }
+ public Action Action { get; }
+ }
+
+ // Registers a hot key with Windows.
+ [DllImport("user32.dll")]
+ private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
+ // Unregisters the hot key with Windows.
+ [DllImport("user32.dll")]
+ private static extern bool UnregisterHotKey(IntPtr hWnd, int id);
+
+ private class InvisibleWindowForMessages : System.Windows.Forms.NativeWindow, IDisposable
+ {
+ public InvisibleWindowForMessages()
+ {
+ CreateHandle(new System.Windows.Forms.CreateParams());
+ }
+
+ private static int WM_HOTKEY = 0x0312;
+ protected override void WndProc(ref System.Windows.Forms.Message m)
+ {
+ base.WndProc(ref m);
+
+ if (m.Msg == WM_HOTKEY)
+ {
+ var aWPFKey = KeyInterop.KeyFromVirtualKey((int)m.LParam >> 16 & 0xFFFF);
+ ModifierKeys modifier = (ModifierKeys)((int)m.LParam & 0xFFFF);
+ if (KeyPressed != null)
+ {
+ KeyPressed(this, new HotKeyPressedEventArgs(modifier, aWPFKey));
+ }
+ }
+ }
+
+ public class HotKeyPressedEventArgs : EventArgs
+ {
+ private ModifierKeys _modifier;
+ private Key _key;
+
+ internal HotKeyPressedEventArgs(ModifierKeys modifier, Key key)
+ {
+ _modifier = modifier;
+ _key = key;
+ }
+
+ public ModifierKeys Modifier
+ {
+ get { return _modifier; }
+ }
+
+ public Key Key
+ {
+ get { return _key; }
+ }
+ }
+
+
+ public event EventHandler KeyPressed;
+
+ #region IDisposable Members
+
+ public void Dispose()
+ {
+ DestroyHandle();
+ }
+
+ #endregion
+ }
+ }
+}
\ No newline at end of file
diff --git a/Overlays/ingame/public/backgrounds/ScoreTeamIconBGLeft.png b/Overlays/ingame/public/backgrounds/ScoreTeamIconBGLeft.png
index 3a56fbd..366be93 100644
Binary files a/Overlays/ingame/public/backgrounds/ScoreTeamIconBGLeft.png and b/Overlays/ingame/public/backgrounds/ScoreTeamIconBGLeft.png differ
diff --git a/Overlays/ingame/public/backgrounds/ScoreTeamIconBGRight.png b/Overlays/ingame/public/backgrounds/ScoreTeamIconBGRight.png
index 2dc2da1..02b8a65 100644
Binary files a/Overlays/ingame/public/backgrounds/ScoreTeamIconBGRight.png and b/Overlays/ingame/public/backgrounds/ScoreTeamIconBGRight.png differ