diff --git a/Lithium/ConfigLoader.cs b/Lithium/ConfigLoader.cs index ec349da..657d0ed 100644 --- a/Lithium/ConfigLoader.cs +++ b/Lithium/ConfigLoader.cs @@ -18,6 +18,10 @@ namespace Lua public static int prevSetKey = 0x06; // XBUTTON2 public static int refreshKey = 0x50; // P public static int switchSideKey = 0x4D; // M + public static int shootKey = 0x01; // Left mouse button + public static int altShootKey = 0x02; + + // Favorites and user public static string favoriteAttackers = null; diff --git a/Lithium/Lithium.csproj b/Lithium/Lithium.csproj index 2cf98ac..16400eb 100644 --- a/Lithium/Lithium.csproj +++ b/Lithium/Lithium.csproj @@ -51,6 +51,9 @@ prompt 4 + + a23ae8c4c6863364165637fb70679eb3.ico + ..\packages\Microsoft.Bcl.AsyncInterfaces.10.0.0\lib\net462\Microsoft.Bcl.AsyncInterfaces.dll @@ -172,19 +175,22 @@ + latest This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - - - - - - + + + + + + + + + + + \ No newline at end of file diff --git a/Lithium/MainWindow.xaml.cs b/Lithium/MainWindow.xaml.cs index eb0faf8..db00b3c 100644 --- a/Lithium/MainWindow.xaml.cs +++ b/Lithium/MainWindow.xaml.cs @@ -14,79 +14,136 @@ namespace Lithium { private bool customSetEnabled = false; + // Hotkey debounce flags + private bool nextSetHeld = false; + private bool prevSetHeld = false; + private bool refreshHeld = false; + private bool switchSideHeld = false; + public MainWindow() { InitializeComponent(); - // Load configs AppendConsole("Initializing Lithium..."); + ConfigLoader.LoadInitConfig(); OperatorSets.LoadOperatorSets(); AppendConsole("Loaded Operators | Current Set: " + OperatorSets.CurrentSet); - // Load website inside browse string url = OperatorSets.ConfigExportUrl; - Browser.Source = !string.IsNullOrEmpty(url) ? new Uri(url) : new Uri("https://jj.giggity.gay/exindex.html"); + Browser.Source = !string.IsNullOrEmpty(url) + ? new Uri(url) + : new Uri("https://jj.giggity.gay/exindex.html"); - - Thread hotkeyThread = new Thread(HotkeyLoop) - { - IsBackground = true - }; + // Start hotkey watcher + Thread hotkeyThread = new Thread(HotkeyLoop); + hotkeyThread.IsBackground = true; hotkeyThread.Start(); + + // Start recoil worker + Thread recoilThread = new Thread(RecoilLoop); + recoilThread.IsBackground = true; + recoilThread.Start(); } - #region Keybinds + // ============================================================ + // RECOIL SYSTEM (THIS IS WHAT WAS MISSING) + // ============================================================ + private void RecoilLoop() + { + const int RIGHT_MOUSE = 0x02; // Right mouse button + + while (true) + { + bool leftPressed = Utils.IsPressed(ConfigLoader.shootKey); // 0x01 + bool rightPressed = Utils.IsPressed(RIGHT_MOUSE); // 0x02 + + // Only trigger recoil when BOTH are held + bool shouldFire = leftPressed && rightPressed; + + if (shouldFire) + { + var recoil = OperatorSets.GetCurrentRecoil(); + + if (recoil.recoilX != 0 || recoil.recoilY != 0) + { + Utils.MoveMouse( + (int)Math.Round(recoil.recoilX), + (int)Math.Round(recoil.recoilY) + ); + } + } + + Thread.Sleep(1); + } + } + + + + + // ============================================================ + // HOTKEY THREAD (debounced) + // ============================================================ private void HotkeyLoop() { while (true) { // Next Set - if (Utils.IsPressed(ConfigLoader.nextSetKey)) + bool nextDown = Utils.IsPressed(ConfigLoader.nextSetKey); + if (nextDown && !nextSetHeld) { + nextSetHeld = true; OperatorSets.NextSet(); AppendConsole("Next Set → " + OperatorSets.CurrentSet); Utils.SafeSpeak(OperatorSets.CurrentSet); - Thread.Sleep(200); } + if (!nextDown) nextSetHeld = false; // Previous Set - if (Utils.IsPressed(ConfigLoader.prevSetKey)) + bool prevDown = Utils.IsPressed(ConfigLoader.prevSetKey); + if (prevDown && !prevSetHeld) { + prevSetHeld = true; OperatorSets.PreviousSet(); AppendConsole("Previous Set → " + OperatorSets.CurrentSet); Utils.SafeSpeak(OperatorSets.CurrentSet); - Thread.Sleep(200); } + if (!prevDown) prevSetHeld = false; - // Reload Config - if (Utils.IsPressed(ConfigLoader.refreshKey)) + // Reload config + bool refreshDown = Utils.IsPressed(ConfigLoader.refreshKey); + if (refreshDown && !refreshHeld) { + refreshHeld = true; OperatorSets.LoadOperatorSets(); AppendConsole("Reloaded config."); - Thread.Sleep(300); } + if (!refreshDown) refreshHeld = false; // Switch Side - if (Utils.IsPressed(ConfigLoader.switchSideKey)) + bool switchDown = Utils.IsPressed(ConfigLoader.switchSideKey); + if (switchDown && !switchSideHeld) { + switchSideHeld = true; OperatorSets.SwitchSide(); AppendConsole("Switched side → " + (OperatorSets.onAttackers ? "Attackers" : "Defenders")); - Thread.Sleep(250); } + if (!switchDown) switchSideHeld = false; - Thread.Sleep(10); + Thread.Sleep(8); } } - #endregion - #region Console Append + // ============================================================ + // SAFE UI CONSOLE APPEND + // ============================================================ public void AppendConsole(string msg) { Dispatcher.Invoke(() => { - ConsoleOutput.Text += msg + "\n"; + ConsoleOutput.Text += msg + Environment.NewLine; + ConsoleScroll.ScrollToBottom(); }); } @@ -97,10 +154,10 @@ namespace Lithium CustomSetConsole.Text = msg; }); } - #endregion - - #region Custom Set Builder Handlers + // ============================================================ + // CUSTOM SET BUILDER + // ============================================================ private void ToggleCustomSet_Click(object sender, RoutedEventArgs e) { customSetEnabled = !customSetEnabled; @@ -131,23 +188,23 @@ namespace Lithium try { + HttpClient client = new HttpClient(); string json = JsonSerializer.Serialize(payload); - using (HttpClient client = new HttpClient()) - { - var content = new StringContent(json, Encoding.UTF8, "application/json"); - HttpResponseMessage response = await client.PostAsync("https://jj.giggity.gay/api/global/add", content); + var content = new StringContent(json, Encoding.UTF8, "application/json"); + var response = await client.PostAsync("https://jj.giggity.gay/api/global/add", content); - if (response.IsSuccessStatusCode) - { - UpdateCustomSetConsole($"Successfully published: {name} ({type}) X:{x} Y:{y}"); - } - else - { - string errorText = await response.Content.ReadAsStringAsync(); - UpdateCustomSetConsole($"Failed to publish: {response.StatusCode} - {errorText}"); - } + if (response.IsSuccessStatusCode) + { + UpdateCustomSetConsole($"Successfully published: {name} ({type}) X:{x} Y:{y}"); } + else + { + string errorText = await response.Content.ReadAsStringAsync(); + UpdateCustomSetConsole($"Failed: {response.StatusCode} - {errorText}"); + } + + client.Dispose(); } catch (Exception ex) { @@ -159,8 +216,9 @@ namespace Lithium { try { - string path = "custom_set.txt"; - File.WriteAllText(path, $"{OperatorNameTextBox.Text}|{RecoilXTextBox.Text}|{RecoilYTextBox.Text}|{(AttackerRadioButton.IsChecked == true ? "attacker" : "defender")}"); + File.WriteAllText("custom_set.txt", + $"{OperatorNameTextBox.Text}|{RecoilXTextBox.Text}|{RecoilYTextBox.Text}|{(AttackerRadioButton.IsChecked == true ? "attacker" : "defender")}"); + UpdateCustomSetConsole("Custom set saved"); } catch @@ -173,21 +231,23 @@ namespace Lithium { try { - string path = "custom_set.txt"; - if (!File.Exists(path)) + if (!File.Exists("custom_set.txt")) { UpdateCustomSetConsole("No saved set found"); return; } - string[] parts = File.ReadAllText(path).Split('|'); - if (parts.Length != 4) throw new Exception("Invalid file format"); + string[] parts = File.ReadAllText("custom_set.txt").Split('|'); + if (parts.Length != 4) throw new Exception("Invalid file"); OperatorNameTextBox.Text = parts[0]; RecoilXTextBox.Text = parts[1]; RecoilYTextBox.Text = parts[2]; - if (parts[3].ToLower() == "attacker") AttackerRadioButton.IsChecked = true; - else DefenderRadioButton.IsChecked = true; + + if (parts[3].Equals("attacker", StringComparison.OrdinalIgnoreCase)) + AttackerRadioButton.IsChecked = true; + else + DefenderRadioButton.IsChecked = true; UpdateCustomSetConsole("Custom set loaded"); } @@ -196,7 +256,5 @@ namespace Lithium UpdateCustomSetConsole("Failed to load custom set"); } } - - #endregion } } diff --git a/Lithium/OperatorSets.cs b/Lithium/OperatorSets.cs index b213b65..d9bac22 100644 --- a/Lithium/OperatorSets.cs +++ b/Lithium/OperatorSets.cs @@ -22,18 +22,23 @@ namespace Lua public static List attackerNames = new List(); public static List defenderNames = new List(); - public static List setNames = new List(); public static int currentSetIndex = 0; public static bool onAttackers = true; + // ====================================================== + // ONLINE CONFIG URL + // ====================================================== + private static string OnlineConfigUrl => + string.IsNullOrEmpty(ConfigLoader.userName) + ? null + : $"https://jj.giggity.gay/api/config/export?name={Uri.EscapeDataString(ConfigLoader.userName)}"; + public static string ConfigExportUrl => - string.IsNullOrEmpty(ConfigLoader.userName) - ? null - : $"https://jj.giggity.gay/exindex.html?name={Uri.EscapeDataString(ConfigLoader.userName)}"; - - + string.IsNullOrEmpty(ConfigLoader.userName) + ? null + : $"https://jj.giggity.gay/exindex.html?name={Uri.EscapeDataString(ConfigLoader.userName)}"; // ====================================================== // CURRENT SET + CURRENT OPERATOR @@ -67,13 +72,21 @@ namespace Lua } } + // ====================================================== + // GET CURRENT RECOIL + // ====================================================== + public static (double recoilX, double recoilY) GetCurrentRecoil() + { + string op = CurrentOperator; - // Build online URL - private static string OnlineConfigUrl => - string.IsNullOrEmpty(ConfigLoader.userName) - ? null - : $"https://jj.giggity.gay/api/config/export?name={Uri.EscapeDataString(ConfigLoader.userName)}"; + if (onAttackers && attackers.ContainsKey(op)) + return attackers[op]; + if (!onAttackers && defenders.ContainsKey(op)) + return defenders[op]; + + return (0, 0); + } // ====================================================== // LOAD CONFIG @@ -99,10 +112,7 @@ namespace Lua allLines.AddRange(txt.Split('\n')); } } - catch - { - // ignored - } + catch { } } // ---------- LOCAL ---------- @@ -122,19 +132,14 @@ namespace Lua if (line.StartsWith("--") || line.StartsWith("#")) continue; if (line.StartsWith("attackers", StringComparison.OrdinalIgnoreCase)) - { - inAtk = true; inDef = false; continue; - } - if (line.StartsWith("defenders", StringComparison.OrdinalIgnoreCase)) - { - inAtk = false; inDef = true; continue; - } - if (line == "}" || line == "]," || line == "],") - { - inAtk = false; inDef = false; continue; - } + { inAtk = true; inDef = false; continue; } + + if (line.StartsWith("defenders", StringComparison.OrdinalIgnoreCase)) + { inAtk = false; inDef = true; continue; } + + if (line == "}" || line == "]," || line == "],") + { inAtk = false; inDef = false; continue; } - // parse recoil line if (Helper.TryParseRecoilLine(line, out var name, out var x, out var y)) { if (inAtk) @@ -153,12 +158,10 @@ namespace Lua MergeSets(); RestoreFavorites(); - // correct operator selection if (setNames.Count > 0) CurrentOperator = CurrentSet; } - // ====================================================== // MERGE // ====================================================== @@ -167,11 +170,8 @@ namespace Lua if (ConfigLoader.betaTest) { mergedSets.Clear(); - - foreach (var kv in attackers) - mergedSets[kv.Key] = kv.Value; - foreach (var kv in defenders) - mergedSets[kv.Key] = kv.Value; + foreach (var kv in attackers) mergedSets[kv.Key] = kv.Value; + foreach (var kv in defenders) mergedSets[kv.Key] = kv.Value; setNames = attackerNames.Concat(defenderNames) .Distinct(StringComparer.OrdinalIgnoreCase) @@ -192,27 +192,19 @@ namespace Lua currentSetIndex = Helper.SafeClampIndex(currentSetIndex, setNames.Count); } - // ====================================================== // RESTORE // ====================================================== public static void RestoreSet(string oldSet) { - if (setNames.Count == 0) - { - currentSetIndex = 0; - return; - } - - int idx = setNames.FindIndex(s => - string.Equals(s, oldSet, StringComparison.OrdinalIgnoreCase)); + if (setNames.Count == 0) { currentSetIndex = 0; return; } + int idx = setNames.FindIndex(s => string.Equals(s, oldSet, StringComparison.OrdinalIgnoreCase)); currentSetIndex = idx >= 0 ? idx : 0; CurrentOperator = CurrentSet; } - // ====================================================== // SWITCH SIDE // ====================================================== @@ -225,7 +217,6 @@ namespace Lua RestoreFavorites(); } - // ====================================================== // CYCLING // ====================================================== @@ -245,17 +236,12 @@ namespace Lua CurrentOperator = CurrentSet; } - // ====================================================== // FAVORITES // ====================================================== private static void RestoreFavorites() { - if (setNames.Count == 0) - { - currentSetIndex = 0; - return; - } + if (setNames.Count == 0) { currentSetIndex = 0; return; } if (ConfigLoader.betaTest) { @@ -264,7 +250,6 @@ namespace Lua { currentSetIndex = setNames.FindIndex(s => string.Equals(s, ConfigLoader.favoriteAttackers, StringComparison.OrdinalIgnoreCase)); - CurrentOperator = CurrentSet; return; } @@ -274,7 +259,6 @@ namespace Lua { currentSetIndex = setNames.FindIndex(s => string.Equals(s, ConfigLoader.favoriteDefenders, StringComparison.OrdinalIgnoreCase)); - CurrentOperator = CurrentSet; return; } @@ -284,34 +268,26 @@ namespace Lua return; } - // non-beta side-based - if (onAttackers) + if (onAttackers && !string.IsNullOrEmpty(ConfigLoader.favoriteAttackers) && + setNames.Contains(ConfigLoader.favoriteAttackers, StringComparer.OrdinalIgnoreCase)) { - if (!string.IsNullOrEmpty(ConfigLoader.favoriteAttackers) && - setNames.Contains(ConfigLoader.favoriteAttackers, StringComparer.OrdinalIgnoreCase)) - { - currentSetIndex = setNames.FindIndex(s => - string.Equals(s, ConfigLoader.favoriteAttackers, StringComparison.OrdinalIgnoreCase)); - - CurrentOperator = CurrentSet; - return; - } + currentSetIndex = setNames.FindIndex(s => + string.Equals(s, ConfigLoader.favoriteAttackers, StringComparison.OrdinalIgnoreCase)); + CurrentOperator = CurrentSet; + return; } - else - { - if (!string.IsNullOrEmpty(ConfigLoader.favoriteDefenders) && - setNames.Contains(ConfigLoader.favoriteDefenders, StringComparer.OrdinalIgnoreCase)) - { - currentSetIndex = setNames.FindIndex(s => - string.Equals(s, ConfigLoader.favoriteDefenders, StringComparison.OrdinalIgnoreCase)); - CurrentOperator = CurrentSet; - return; - } + if (!onAttackers && !string.IsNullOrEmpty(ConfigLoader.favoriteDefenders) && + setNames.Contains(ConfigLoader.favoriteDefenders, StringComparer.OrdinalIgnoreCase)) + { + currentSetIndex = setNames.FindIndex(s => + string.Equals(s, ConfigLoader.favoriteDefenders, StringComparison.OrdinalIgnoreCase)); + CurrentOperator = CurrentSet; + return; } currentSetIndex = 0; CurrentOperator = CurrentSet; } } -} \ No newline at end of file +} diff --git a/Lithium/RecoilControl.cs b/Lithium/RecoilControl.cs index 0ab5da5..e93419e 100644 --- a/Lithium/RecoilControl.cs +++ b/Lithium/RecoilControl.cs @@ -1,5 +1,4 @@ -// RecoilControl.cs (patched) -using System; +using System; using System.Threading; namespace Lua @@ -41,7 +40,7 @@ namespace Lua if (!Utils.IsPressed(VK_LBUTTON)) return; - var setName = OperatorSets.CurrentSet; + string setName = OperatorSets.CurrentSet; if (!OperatorSets.mergedSets.TryGetValue(setName, out var recoil)) return; @@ -87,6 +86,7 @@ namespace Lua moveY *= 1.351; } + // CAST doubles to int to fix compiler errors int ix = (int)Math.Round(moveX); int iy = (int)Math.Round(moveY); @@ -96,4 +96,4 @@ namespace Lua Utils.MoveMouse(ix, iy); } } -} \ No newline at end of file +} diff --git a/Lithium/a23ae8c4c6863364165637fb70679eb3.ico b/Lithium/a23ae8c4c6863364165637fb70679eb3.ico new file mode 100644 index 0000000..1d592a3 Binary files /dev/null and b/Lithium/a23ae8c4c6863364165637fb70679eb3.ico differ diff --git a/Lithium/bin/Lithium.7z b/Lithium/bin/Lithium.7z index 90d7b8c..6a3f7c5 100644 Binary files a/Lithium/bin/Lithium.7z and b/Lithium/bin/Lithium.7z differ