diff --git a/README.md b/README.md
index 767aba3..f58275e 100644
--- a/README.md
+++ b/README.md
@@ -7,17 +7,28 @@
# ValorantCC (Valorant Crosshair Changer) [Download Here](https://github.com/weedeej/ValorantCC/releases/latest/download/ValorantCC.exe)
Change your Crosshair's color to **ANY** color you want for style and/or visiblity.
-
+![image](https://user-images.githubusercontent.com/87055977/155284250-d01577c2-5661-43b1-8759-a6a8525e7709.png)
+
+Share your crosshair across the ValorantCC comunity!
+![image](https://user-images.githubusercontent.com/87055977/155284365-c802a73e-5062-4d36-b089-4116c2d85e9a.png)
+
+## Requirement
+- .NET6.0 (This comes with windows updates. If you have the latest version of windows, This should be installed automatically. if not, download .NET6.0 **DESKTOP RUNTIME**.
## Usage
- Either Open this first or Riot client or Valorant it doesn't matter.
-- Click Login on this app.
-- Select the profile you want to change color.
-- Change to color.
+- Wait for the app to login itself.
+- Select the profile you want to change color via the dropdown on top-right.
+- Change the colors.
- Save.
-- Restart Valorant \*(**IMPORTANT**)\*.
+- Restart Valorant if Valorant is running \*(**IMPORTANT**)\*.
-Also don't forget to enjoy.
+##
+- If you experience any Issues such as not working, Join us on [Discord](https://discord.gg/ME5EdK8U9v) and we'll try to fix it.
+- You don't need to keep this app running in the background. Once you saved it, It will stay there.
+- This does not change the game files nor touch Valorant's memory related stuff. The app only uses the Client API and send it directly to Valorant's Server.
+- Yes. Other players can see it too as it is saved server side.
+- THIS IS **NOT** AN OVERLAY/HACK/CHEAT/AIMBOT.
## Disclaimer
The images, endpoints and other material used in this project are owned by Riot Games.
diff --git a/ValorantCC/App.xaml b/ValorantCC/App.xaml
index c84e840..3bde1c2 100644
--- a/ValorantCC/App.xaml
+++ b/ValorantCC/App.xaml
@@ -4,220 +4,15 @@
xmlns:local="clr-namespace:ValorantCC"
StartupUri="MainWindow.xaml">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
diff --git a/ValorantCC/App.xaml.cs b/ValorantCC/App.xaml.cs
index 22b1cb2..d988525 100644
--- a/ValorantCC/App.xaml.cs
+++ b/ValorantCC/App.xaml.cs
@@ -1,12 +1,10 @@
using System;
+using System.Runtime.ExceptionServices;
+using System.Threading.Tasks;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Threading;
-using System.Threading;
-using Utilities;
-using System.Runtime.ExceptionServices;
-using System.Threading.Tasks;
namespace ValorantCC
{
@@ -19,7 +17,7 @@ protected override void OnStartup(StartupEventArgs e)
{
//Copy pasta for logging :V
Startup += new StartupEventHandler(AppEventHandler);
-
+
DispatcherUnhandledException += LogDispatcherUnhandled;
TaskScheduler.UnobservedTaskException += LogUnobservedTaskException;
@@ -34,12 +32,12 @@ private void AppEventHandler(object sender, StartupEventArgs e)
private void LogFirstChanceException(object sender, FirstChanceExceptionEventArgs e)
{
- Utils.Log($"{e.Exception.Message}: {e.Exception.StackTrace}");
+ Utilities.Utils.Log($"{e.Exception.Message}: {e.Exception.StackTrace}");
}
private void LogDispatcherUnhandled(object sender, DispatcherUnhandledExceptionEventArgs e)
{
- Utils.Log($"{e.Exception.Message}: {e.Exception.StackTrace}");
+ Utilities.Utils.Log($"{e.Exception.Message}: {e.Exception.StackTrace}");
e.Handled = false;
}
@@ -48,13 +46,13 @@ private void LogUnhandled(object sender, UnhandledExceptionEventArgs e)
var ex = e.ExceptionObject as Exception;
if (e.IsTerminating)
{
- Utils.Log($"{ex.Message}: {ex.StackTrace}");
+ Utilities.Utils.Log($"{ex.Message}: {ex.StackTrace}");
}
}
private void LogUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
{
- Utils.Log($"{e.Exception.Message}: {e.Exception.StackTrace}");
+ Utilities.Utils.Log($"{e.Exception.Message}: {e.Exception.StackTrace}");
e.SetObserved();
}
}
diff --git a/ValorantCC/MainWindow.xaml b/ValorantCC/MainWindow.xaml
index 6a53b93..10ad1c7 100644
--- a/ValorantCC/MainWindow.xaml
+++ b/ValorantCC/MainWindow.xaml
@@ -1,105 +1,64 @@
-
+
-
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -127,11 +86,13 @@
+
-
-
-
-
+
+
+
+
+
@@ -159,84 +120,139 @@
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
diff --git a/ValorantCC/MainWindow.xaml.cs b/ValorantCC/MainWindow.xaml.cs
index fe3c342..1e028ce 100644
--- a/ValorantCC/MainWindow.xaml.cs
+++ b/ValorantCC/MainWindow.xaml.cs
@@ -1,69 +1,54 @@
using EZ_Updater;
+using MahApps.Metro.Controls;
+using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
+using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
-using System.Windows.Shapes;
-using Utilities;
using ValorantCC.src;
+using ValorantCC.SubWindow;
namespace ValorantCC
{
- public partial class MainWindow : Window
+ public partial class MainWindow : MetroWindow
{
- Processor DataProcessor = new Processor();
- bool LoggedIn;
- CrosshairProfile SelectedProfile;
- List SelectedColors;
- int SelectedIndex;
+ public Processor DataProcessor = new Processor();
BrushConverter bc = new BrushConverter();
- readonly string LoggingDir = Environment.GetEnvironmentVariable("LocalAppData") + @"\VTools\Logs\";
+ public AuthResponse AuthResponse;
+ public CrosshairProfile SelectedProfile;
+ List SelectedColors;
+ public API ValCCAPI;
+ public int SelectedIndex;
+ public bool LoggedIn;
+ private string _sharecode;
+ private FetchResponse? sharedProfileResp;
public MainWindow()
{
// Create logging dir
- if (!Directory.Exists(LoggingDir)) Directory.CreateDirectory(LoggingDir);
- // Replace old logs
- string LogFile = LoggingDir + "/logs.txt";
- if (File.Exists(LogFile)) File.Move(LogFile, LogFile + ".old", true);
+ if (!Directory.Exists(Path.GetDirectoryName(Utilities.Utils.LoggingFile))) Directory.CreateDirectory(Path.GetDirectoryName(Utilities.Utils.LoggingFile));
+ // Replace old logs
+ if (File.Exists(Utilities.Utils.LoggingFile)) File.Move(Utilities.Utils.LoggingFile, Path.GetDirectoryName(Utilities.Utils.LoggingFile) + "\\" + Path.GetFileNameWithoutExtension(Utilities.Utils.LoggingFile) + "-old" + Path.GetExtension(Utilities.Utils.LoggingFile), true);
Version ProgramFileVersion = new Version(FileVersionInfo.GetVersionInfo(Process.GetCurrentProcess().MainModule.FileName).ProductVersion);
InitializeComponent();
- Utils.Log($"App Started | v{ProgramFileVersion}. Replaced old logfile.");
- Txt_CurrVer.Content = $"v{ProgramFileVersion}";
- }
-
- private async void Grid_Loaded(object sender, RoutedEventArgs e)
- {
- Updater.CustomLogger = Utils.Log;
- Updater.OriginalFileName = "ValorantCC";
- if (await Updater.CheckUpdateAsync("weedeej", "ValorantCC"))
- {
- try
- {
- File.Create("./valccPermsTest.null").Close();
- File.Delete("./valccPermsTest.null");
- }
- catch(UnauthorizedAccessException)
- {
- Utils.Log("User is not authorized to create a file on current valcc dir. Consider moving.");
- MessageBox.Show("There's an update available but you have no access to write on this folder.\nPlease consider moving the app to a folder created by you or running the app as administrator.");
- this.Close();
- }
- var update = new UpdateWindow();
- update.Owner = this;
- update.ShowDialog();
- }
+ Utilities.Utils.Log($"App Started | v{ProgramFileVersion}. Replaced old logfile.");
+ this.Title = $"ValorantCC v{ProgramFileVersion}";
+ BackgroundAuth auth = new BackgroundAuth(DataProcessor);
+ auth.LoopCheck();
+ Random nClicks = new Random();
+ for (int i = 0; i < nClicks.Next(0, Resources.MergedDictionaries[0].Count - 1); i++)
+ next_Click(null, null);
}
-
- private void btnSave_Click(object sender, RoutedEventArgs e)
+ private async void btnSave_Click(object sender, RoutedEventArgs e)
{
if (!LoggedIn)
{
- MessageBox.Show("You are not logged in!");
+ Utilities.Utils.MessageText("You are not logged in!", Brushes.Red);
return;
}
if (DataProcessor.ProfileListed)
@@ -74,36 +59,20 @@ private void btnSave_Click(object sender, RoutedEventArgs e)
{
SelectedColors = new List { (Color)primary_color.SelectedColor };
}
- if (DataProcessor.SaveNewColor(SelectedColors, profiles.SelectedIndex, profiles.Text))
+ if (await DataProcessor.SaveNewColor(SelectedColors, profiles.SelectedIndex, profiles.Text))
{
- DataProcessor.Construct();
+ await DataProcessor.Construct();
profiles.Items.Refresh();
profiles.SelectedIndex = DataProcessor.CurrentProfile;
- MessageBox.Show("Saved! If Valorant is open, Please restart it without touching the settings.");
- return;
- }
- MessageBox.Show("Failed. Consult the developer.");
- return;
- }
- private void btnLogin_Click(object sender, RoutedEventArgs e)
- {
- AuthResponse AuthResponse = DataProcessor.Login();
- LoggedIn = AuthResponse.Success;
- if (!LoggedIn)
- {
- MessageBox.Show(AuthResponse.Response);
+ Utilities.Utils.MessageText("Saved! Restart Valorant.", Brushes.Lime);
return;
}
+ Utilities.Utils.MessageText("Your session expired! Please restart ValorantCC/Valorant", Brushes.Red);
- profiles.ItemsSource = DataProcessor.ProfileNames;
- txt_LoggedIn.Foreground = Brushes.Lime;
- profiles.SelectedIndex = DataProcessor.CurrentProfile;
- profiles.IsReadOnly = false;
- MessageBox.Show(Utils.LoginResponse(DataProcessor));
- btnLogin.IsEnabled = true;
+ return;
}
- private void profiles_SelectionChanged(object sender, SelectionChangedEventArgs e)
+ private async void profiles_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (profiles.SelectedIndex == -1) return;
@@ -121,11 +90,34 @@ private void profiles_SelectionChanged(object sender, SelectionChangedEventArgs
}
prim_outline_color.SelectedColor = Color.FromRgb(SelectedProfile.Primary.OutlineColor.R, SelectedProfile.Primary.OutlineColor.G, SelectedProfile.Primary.OutlineColor.B);
if (SelectedProfile.aDS == null) SelectedProfile.aDS = SelectedProfile.Primary;
- if(SelectedProfile.bUsePrimaryCrosshairForADS) SelectedProfile.aDS.Color = SelectedProfile.Primary.Color;
+ if (SelectedProfile.bUsePrimaryCrosshairForADS) SelectedProfile.aDS.Color = SelectedProfile.Primary.Color;
ads_color.SelectedColor = Color.FromRgb(SelectedProfile.aDS.Color.R, SelectedProfile.aDS.Color.G, SelectedProfile.aDS.Color.B);
ads_outline_color.SelectedColor = Color.FromRgb(SelectedProfile.aDS.OutlineColor.R, SelectedProfile.aDS.OutlineColor.G, SelectedProfile.aDS.OutlineColor.B);
sniper_dot_color.SelectedColor = Color.FromRgb(SelectedProfile.Sniper.CenterDotColor.R, SelectedProfile.Sniper.CenterDotColor.G, SelectedProfile.Sniper.CenterDotColor.B);
-
+ if (!sharedProfileResp.HasValue)
+ {
+ if (ValCCAPI != null) sharedProfileResp = await ValCCAPI.ObtainSelfSaved();
+ }
+ else
+ {
+ var respData = sharedProfileResp.Value;
+ if (respData.success && respData.data != null)
+ {
+ var data = respData.data.FirstOrDefault();
+ _sharecode = data.shareCode;
+ CrosshairProfile fromDb = JsonConvert.DeserializeObject(data.settings);
+ if (SelectedProfile.ProfileName == fromDb.ProfileName)
+ {
+ chkbxShareable.IsChecked = data.shareable;
+ btnCopyShareCode.Visibility = Visibility.Visible;
+ }
+ else
+ {
+ chkbxShareable.IsChecked = false;
+ btnCopyShareCode.Visibility = Visibility.Collapsed;
+ }
+ }
+ }
Crosshair_load();
}
private void StackPanel_MouseDown(object sender, MouseButtonEventArgs e)
@@ -133,15 +125,17 @@ private void StackPanel_MouseDown(object sender, MouseButtonEventArgs e)
if (e.LeftButton == MouseButtonState.Pressed) DragMove();
}
- private void btnReload_Click(object sender, RoutedEventArgs e)
+ private async void btnReload_Click(object sender, RoutedEventArgs e)
{
if (!LoggedIn)
{
- MessageBox.Show("You are not logged in!");
+ Utilities.Utils.MessageText("You are not logged in!", Brushes.Red);
return;
}
- Utils.Log("Reload Clicked > Reconstructing Processor.");
- DataProcessor.Construct();
+ Utilities.Utils.Log("Reload Clicked > Reconstructing Processor.");
+ if (!(await DataProcessor.Construct()))
+ Utilities.Utils.MessageText("Your session expired! Please restart ValorantCC/Valorant", Brushes.Red);
+
profiles.ItemsSource = DataProcessor.ProfileNames;
profiles.Items.Refresh();
profiles.SelectedIndex = DataProcessor.CurrentProfile;
@@ -155,7 +149,7 @@ private void profiles_TextChanged(object sender, TextChangedEventArgs e)
profiles.SelectedIndex = SelectedIndex;
}
- private void Crosshair_load()
+ public void Crosshair_load()
{
//Primary
Crosshair_Parser.dot_redraw(primeDOT, primeDOTOT, SelectedProfile.Primary);
@@ -271,19 +265,23 @@ private void TabButtonLeave(object sender, MouseEventArgs e)
private void ClipboardButtonEnter(object sender, MouseEventArgs e)
{
- CopyButtonLabel.FontSize += 1;
+ Button button = (Button)sender;
+ if (button.Name == "btnCopyLogs") CopyButtonLabel.FontSize += 1;
+ else communitylist_label.FontSize += 1;
}
private void ClipboardButtonLeave(object sender, MouseEventArgs e)
{
- CopyButtonLabel.FontSize -= 1;
+ Button button = (Button)sender;
+ if (button.Name == "btnCopyLogs") CopyButtonLabel.FontSize -= 1;
+ else communitylist_label.FontSize -= 1;
}
private void btnOpenLogs_Click(object sender, RoutedEventArgs e)
{
Process p = new Process();
- p.StartInfo = new ProcessStartInfo() { FileName = LoggingDir, UseShellExecute = true };
+ p.StartInfo = new ProcessStartInfo() { FileName = Path.GetDirectoryName(Utilities.Utils.LoggingFile), UseShellExecute = true };
p.Start();
- MessageBox.Show("Log folder opened. Please include the OLD file on your report as this helps us recreate the bug/error you will report.");
+ Utilities.Utils.MessageText("Log folder opened! Please include OLD files to your report if exists.", Brushes.Lime);
}
private void next_Click(object sender, RoutedEventArgs e)
@@ -300,12 +298,99 @@ private ImageSource Get_CrosshairBG(bool next = true)
{
int number = int.Parse(System.IO.Path.GetFileNameWithoutExtension(CrosshairBG.Source.ToString()).Replace("CrosshairBG", "")) + (next ? 1 : -1);
- if (next && number > Resources.Count - 1)
+ if (next && number > Resources.MergedDictionaries[0].Count - 1)
number = 0;
else if (number < 0)
- number = Resources.Count - 1;
+ number = Resources.MergedDictionaries[0].Count - 1;
return (ImageSource)FindResource("crosshairBG" + number);
}
+
+ private void btnCommunityProfiles_Click(object sender, RoutedEventArgs e)
+ {
+ if (!LoggedIn)
+ {
+ Utilities.Utils.MessageText("You are not logged in !", Brushes.Red);
+ return;
+ }
+ try
+ {
+ Window publicProfiles = Application.Current.Windows.Cast().Single(window => window.GetType().ToString() == "ValorantCC.ProfilesWindow");
+ publicProfiles.Activate();
+ }
+ catch (Exception)
+ {
+ ProfilesWindow publicProfiles = new ProfilesWindow(SelectedProfile, ValCCAPI);
+ publicProfiles.Owner = this;
+ publicProfiles.Show();
+ }
+ }
+
+ private void chkbxShareable_Click(object sender, RoutedEventArgs e)
+ {
+ if (!LoggedIn)
+ {
+ Utilities.Utils.MessageText("You are not logged in !", Brushes.Red);
+ ((CheckBox)sender).IsChecked = !((CheckBox)sender).IsChecked;
+ return;
+ }
+ }
+
+ private async void btnShare_Click(object sender, RoutedEventArgs e)
+ {
+ if (!LoggedIn)
+ {
+ Utilities.Utils.MessageText("You are not logged in !", Brushes.Red);
+ return;
+ }
+ Utilities.Utils.MessageText("Your profile is being saved...", Brushes.Yellow);
+
+ ValCCAPI.Shareable = (bool)chkbxShareable.IsChecked;
+ ValCCAPI.profile = SelectedProfile;
+ SetCallResponse response = await ValCCAPI.Set();
+ if (!response.success)
+ {
+ Utilities.Utils.Log($"Unable to share crosshair: {response.message}");
+ Utilities.Utils.MessageText("Unable to share crosshair: Internal Error/Conflict", Brushes.Red);
+ return;
+ }
+ String sharecode = response.message;
+ Clipboard.SetText(sharecode);
+ MessageWindow.Show($"Your sharecode is: \"{sharecode}\" and is copied.\nIf you want this profile accessible across the community,\nPlease be sure that you have the 'shareable' checkbox checked.", "Profile shared!");
+
+ Utilities.Utils.MessageText("Your profile has been saved. It can now be browsed if \"shareable\" checkbox is checked before saving.", Brushes.Lime);
+ }
+
+ private async void spinner_Loaded(object sender, RoutedEventArgs e)
+ {
+ Trace.WriteLine(ValorantCC.src.Community.SCGen.GenerateShareCode("64f8b630-64c6-5838-9daa-916f8bbf5587"));
+ Trace.WriteLine(ValorantCC.src.Community.SCGen.GenerateShareCode("b19f4928-e1ed-5f63-a9d0-8a7fd202e3b2"));
+ Updater.CustomLogger = Utilities.Utils.Log;
+ Updater.OriginalFileName = "ValorantCC";
+ Updater.LogInterfix = " | ";
+ if (await Updater.CheckUpdateAsync("weedeej", "ValorantCC"))
+ {
+ if (Updater.CannotWriteOnDir)
+ {
+ Utilities.Utils.Log("User is not authorized to create a file on current valcc dir. Consider moving.");
+ MessageWindow.Show("There's an update available but you have no access to write on this folder.\nPlease consider moving the app to a folder created by you or running the app as administrator.");
+ this.Close();
+ }
+ var update = new UpdateWindow();
+ update.Owner = this;
+ update.ShowDialog();
+ }
+ }
+
+ private void btnCopyShareCode_Click(object sender, RoutedEventArgs e)
+ {
+ Clipboard.SetText(_sharecode);
+ Utilities.Utils.MessageText("Your sharecode has been copied!", Brushes.Lime);
+ }
+
+ private void _zoom_ValueChanged(object sender, RoutedPropertyChangedEventArgs e)
+ {
+ Trace.WriteLine(_zoom.Value);
+ }
}
}
diff --git a/ValorantCC/References/Xceed.Wpf.AvalonDock.Themes.Aero.dll b/ValorantCC/References/Xceed.Wpf.AvalonDock.Themes.Aero.dll
deleted file mode 100644
index 4e51591..0000000
Binary files a/ValorantCC/References/Xceed.Wpf.AvalonDock.Themes.Aero.dll and /dev/null differ
diff --git a/ValorantCC/References/Xceed.Wpf.AvalonDock.dll b/ValorantCC/References/Xceed.Wpf.AvalonDock.dll
deleted file mode 100644
index bbddc15..0000000
Binary files a/ValorantCC/References/Xceed.Wpf.AvalonDock.dll and /dev/null differ
diff --git a/ValorantCC/References/Xceed.Wpf.Toolkit.dll b/ValorantCC/References/Xceed.Wpf.Toolkit.dll
deleted file mode 100644
index e686971..0000000
Binary files a/ValorantCC/References/Xceed.Wpf.Toolkit.dll and /dev/null differ
diff --git a/ValorantCC/Resources/BGdictionary.xaml b/ValorantCC/Resources/BGdictionary.xaml
new file mode 100644
index 0000000..82f69ee
--- /dev/null
+++ b/ValorantCC/Resources/BGdictionary.xaml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ValorantCC/Resources/CrosshairBG1.png b/ValorantCC/Resources/CrosshairBG1.png
index 9c504b0..d98bc01 100644
Binary files a/ValorantCC/Resources/CrosshairBG1.png and b/ValorantCC/Resources/CrosshairBG1.png differ
diff --git a/ValorantCC/Resources/CrosshairBG2.png b/ValorantCC/Resources/CrosshairBG2.png
index 09d5c9d..9002b37 100644
Binary files a/ValorantCC/Resources/CrosshairBG2.png and b/ValorantCC/Resources/CrosshairBG2.png differ
diff --git a/ValorantCC/Resources/CrosshairBG3.png b/ValorantCC/Resources/CrosshairBG3.png
index 81bfa7b..848c834 100644
Binary files a/ValorantCC/Resources/CrosshairBG3.png and b/ValorantCC/Resources/CrosshairBG3.png differ
diff --git a/ValorantCC/Resources/CrosshairBG4.png b/ValorantCC/Resources/CrosshairBG4.png
index e1b6252..e63ecf0 100644
Binary files a/ValorantCC/Resources/CrosshairBG4.png and b/ValorantCC/Resources/CrosshairBG4.png differ
diff --git a/ValorantCC/Resources/CrosshairBG5.png b/ValorantCC/Resources/CrosshairBG5.png
index e619566..b6fe745 100644
Binary files a/ValorantCC/Resources/CrosshairBG5.png and b/ValorantCC/Resources/CrosshairBG5.png differ
diff --git a/ValorantCC/Resources/chevron-up.png b/ValorantCC/Resources/chevron-up.png
new file mode 100644
index 0000000..1fb3c54
Binary files /dev/null and b/ValorantCC/Resources/chevron-up.png differ
diff --git a/ValorantCC/Resources/menu.png b/ValorantCC/Resources/menu.png
new file mode 100644
index 0000000..1354eb8
Binary files /dev/null and b/ValorantCC/Resources/menu.png differ
diff --git a/ValorantCC/Resources/vtspinner optimized.gif b/ValorantCC/Resources/vtspinner optimized.gif
new file mode 100644
index 0000000..299ed7e
Binary files /dev/null and b/ValorantCC/Resources/vtspinner optimized.gif differ
diff --git a/ValorantCC/Resources/vtspinner.gif b/ValorantCC/Resources/vtspinner.gif
new file mode 100644
index 0000000..70bc0a0
Binary files /dev/null and b/ValorantCC/Resources/vtspinner.gif differ
diff --git a/ValorantCC/SubWindow/MessageWindow.xaml b/ValorantCC/SubWindow/MessageWindow.xaml
new file mode 100644
index 0000000..a8305bf
--- /dev/null
+++ b/ValorantCC/SubWindow/MessageWindow.xaml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ValorantCC/SubWindow/MessageWindow.xaml.cs b/ValorantCC/SubWindow/MessageWindow.xaml.cs
new file mode 100644
index 0000000..504999f
--- /dev/null
+++ b/ValorantCC/SubWindow/MessageWindow.xaml.cs
@@ -0,0 +1,32 @@
+using System.Linq;
+using System.Windows;
+
+namespace ValorantCC.SubWindow
+{
+ ///
+ /// Lógica de interacción para MessageWindow.xaml
+ ///
+ public partial class MessageWindow : Window
+ {
+ public static void Show(string Message, string Title = null)
+ {
+ MessageWindow MessageWin = new(Message, Title);
+ MessageWin.Owner = Application.Current.Windows.OfType().FirstOrDefault(x => x.IsActive);
+ MessageWin.ShowDialog();
+ }
+
+ public MessageWindow(string Message, string Title = null)
+ {
+ InitializeComponent();
+ TitleBar.Content = Title;
+ Messagetxtbox.Text = Message;
+ Messagetxtbox.Focusable = false;
+ OKbtn.Focus();
+ }
+
+ private void OKbtn_Click(object sender, RoutedEventArgs e)
+ {
+ Close();
+ }
+ }
+}
diff --git a/ValorantCC/SubWindow/ProfilesWindow.xaml b/ValorantCC/SubWindow/ProfilesWindow.xaml
new file mode 100644
index 0000000..c15976a
--- /dev/null
+++ b/ValorantCC/SubWindow/ProfilesWindow.xaml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+ An error has occured while fetching profiles.
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ValorantCC/SubWindow/ProfilesWindow.xaml.cs b/ValorantCC/SubWindow/ProfilesWindow.xaml.cs
new file mode 100644
index 0000000..3a4e638
--- /dev/null
+++ b/ValorantCC/SubWindow/ProfilesWindow.xaml.cs
@@ -0,0 +1,210 @@
+using MahApps.Metro.Controls;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+using System.Windows.Media;
+using ValorantCC.SubWindow;
+namespace ValorantCC
+{
+ ///
+ /// Interaction logic for ProfilesWindow.xaml
+ ///
+
+ public struct PublicProfile
+ {
+ public String owner { get; set; }
+ public String sharecode { get; set; }
+ public CrosshairProfile settings { get; set; }
+ public int ID { get; set; }
+ }
+
+ public partial class ProfilesWindow : MetroWindow
+ {
+ public CrosshairProfile selected;
+ private static API ValCCApi;
+ private static MainWindow main;
+ private static List PublicProfiles = new List();
+ public ProfilesWindow(CrosshairProfile current, API ValCCAPI)
+ {
+ InitializeComponent();
+ main = (MainWindow)Application.Current.MainWindow;
+ selected = current;
+ ValCCApi = ValCCAPI;
+ Utilities.Utils.Log("Community Profiles Loading...");
+ }
+
+ private async void ShareablesContainer_Loaded(object sender, RoutedEventArgs e)
+ {
+ LoadingPlaceHolder.Visibility = Visibility.Visible;
+ fetchErrorTxt.Visibility = Visibility.Collapsed;
+ try
+ {
+ bool fetchSucc = await InitialFetch();
+ if (!fetchSucc) fetchErrorTxt.Visibility = Visibility.Visible;
+ else
+ {
+ await RenderProfiles();
+ }
+ }
+ catch (Exception ex)
+ {
+ Utilities.Utils.Log(ex.StackTrace.ToString());
+ }
+ LoadingPlaceHolder.Visibility = Visibility.Collapsed;
+ }
+
+ ///
+ /// Returns the searched sharecode or the list of shareables depending if sharecode is provided or not.
+ ///
+ /// Nullable. Searched Code
+ private async Task InitialFetch(String sharecode = null)
+ {
+ Utilities.Utils.Log("Disabling Search button.");
+ btnSearchCode.IsEnabled = false;
+ Utilities.Utils.Log("Clearing arrays.");
+ PublicProfiles.Clear();
+ ShareablesContainer.Children.Clear();
+ List Shareables;
+ if (!string.IsNullOrWhiteSpace(sharecode))
+ {
+ Utilities.Utils.Log($"Fetching profile with code: {sharecode}");
+ FetchResponse fetchResponse = await ValCCApi.Fetch(sharecode);
+ if (!fetchResponse.success) return false;
+ if (fetchResponse.data.Count < 1)
+ {
+ fetchErrorTxt.Text = "User with corresponding sharecode was not found.";
+ btnSearchCode.IsEnabled = true;
+ return false;
+ }
+ Shareables = fetchResponse.data;
+ }
+ else
+ {
+ Utilities.Utils.Log($"Fetching profiles from server");
+ FetchResponse fetchResponse = await ValCCApi.Fetch();
+ if (!fetchResponse.success) return false;
+ Shareables = fetchResponse.data;
+ }
+
+ if (Shareables.Count == 0) return true;
+
+ for (int i = 0; i < Shareables.Count; i++)
+ {
+ ShareableProfile currentShareable = Shareables[i];
+ CrosshairProfile profile;
+ profile = JsonConvert.DeserializeObject(Regex.Unescape(currentShareable.settings));
+ PublicProfiles.Add(new PublicProfile() { owner = currentShareable.displayName, settings = profile, sharecode = currentShareable.shareCode, ID = i });
+ }
+ btnSearchCode.IsEnabled = true;
+ return true;
+ }
+
+ ///
+ /// Render the PublicProfiles var into frontend.
+ ///
+ private async Task RenderProfiles()
+ {
+ UIElementCollection shareablesElement = ShareablesContainer.Children;
+ if (PublicProfiles.Count == 0) return true;
+
+ for (int i = 0; i < PublicProfiles.Count; i++)
+ {
+ PublicProfile profile = PublicProfiles[i];
+ shareablesElement.Add(await this.GenerateRender(profile));
+ }
+ return true;
+ }
+ private async void btnSearchCode_Click(object sender, RoutedEventArgs e)
+ {
+ LoadingPlaceHolder.Visibility = Visibility.Visible;
+ fetchErrorTxt.Visibility = Visibility.Collapsed;
+ try
+ {
+ bool fetchSucc = await InitialFetch(SearchCode.Text);
+ if (!fetchSucc) fetchErrorTxt.Visibility = Visibility.Visible;
+ else
+ await RenderProfiles();
+ }
+ catch (Exception ex)
+ {
+ Utilities.Utils.Log(ex.StackTrace.ToString());
+ }
+ LoadingPlaceHolder.Visibility = Visibility.Collapsed;
+ }
+
+ public void shareBtnClicked(object sender, RoutedEventArgs e)
+ {
+ String shareCode = ((Button)sender).Name.Split('_')[1];
+ Clipboard.SetText(shareCode);
+ MessageWindow.Show("\"" + shareCode + "\" has been copied to clipboard!");
+ Utilities.Utils.Log($"{shareCode} copied to clipboard.");
+ }
+
+ public void detailsBtnClicked(object sender, RoutedEventArgs e)
+ {
+ PublicProfile pressedPubProfile = PublicProfiles[Int32.Parse(((Button)sender).Name.Split('_')[1])];
+ CrosshairProfile pressedProfile = pressedPubProfile.settings;
+ MessageWindow.Show($"{pressedPubProfile.owner}'s Profile: {pressedProfile.ProfileName}\nPrimary:\n\tInner Lines: {pressedProfile.Primary.InnerLines.Opacity}, {pressedProfile.Primary.InnerLines.LineLength}, {pressedProfile.Primary.InnerLines.LineThickness}, {pressedProfile.Primary.InnerLines.LineOffset}\n\tOuter Lines: {pressedProfile.Primary.OuterLines.Opacity}, {pressedProfile.Primary.OuterLines.LineLength}, {pressedProfile.Primary.OuterLines.LineThickness}, {pressedProfile.Primary.OuterLines.LineOffset}\n\nADS:\n\tInner Lines: {pressedProfile.aDS.InnerLines.Opacity}, {pressedProfile.aDS.InnerLines.LineLength}, {pressedProfile.aDS.InnerLines.LineThickness}, {pressedProfile.aDS.InnerLines.LineOffset}\n\tOuter Lines: {pressedProfile.aDS.OuterLines.Opacity}, {pressedProfile.aDS.OuterLines.LineLength}, {pressedProfile.aDS.OuterLines.LineThickness}, {pressedProfile.aDS.OuterLines.LineOffset}");
+ Utilities.Utils.Log($"Details button clicked.");
+ }
+
+ public void applyBtnClicked(object sender, RoutedEventArgs e)
+ {
+ Utilities.Utils.Log("Apply button clicked.");
+ PublicProfile pressedPubProfile = PublicProfiles[Int32.Parse(((Button)sender).Name.Split('_')[1])];
+ CrosshairProfile pressedProfile = pressedPubProfile.settings;
+ selected.aDS = pressedProfile.aDS;
+ selected.Primary = pressedProfile.Primary;
+ selected.Sniper = pressedProfile.Sniper;
+ selected.bUseAdvancedOptions = pressedProfile.bUseAdvancedOptions;
+ selected.bUseCustomCrosshairOnAllPrimary = pressedProfile.bUseCustomCrosshairOnAllPrimary;
+ selected.bUsePrimaryCrosshairForADS = pressedProfile.bUsePrimaryCrosshairForADS;
+
+ main.primary_color.SelectedColor = new Color() { R = selected.Primary.Color.R, G = selected.Primary.Color.G, B = selected.Primary.Color.B, A = selected.Primary.Color.A };
+ main.ads_color.SelectedColor = new Color() { R = selected.aDS.Color.R, G = selected.aDS.Color.G, B = selected.aDS.Color.B, A = selected.aDS.Color.A };
+
+ main.prim_outline_color.SelectedColor = new Color() { R = selected.Primary.OutlineColor.R, G = selected.Primary.OutlineColor.G, B = selected.Primary.OutlineColor.B, A = selected.Primary.OutlineColor.A };
+ main.ads_outline_color.SelectedColor = new Color() { R = selected.aDS.OutlineColor.R, G = selected.aDS.OutlineColor.G, B = selected.aDS.OutlineColor.B, A = selected.aDS.OutlineColor.A };
+
+ main.sniper_dot_color.SelectedColor = new Color() { R = selected.Sniper.CenterDotColor.R, G = selected.Sniper.CenterDotColor.G, B = selected.Sniper.CenterDotColor.B, A = selected.Sniper.CenterDotColor.A };
+ main.SelectedProfile = selected;
+ main.Crosshair_load();
+ }
+
+ private void ExitClick(object sender, RoutedEventArgs e)
+ {
+ Close();
+ }
+ private void MinimizeClick(object sender, RoutedEventArgs e)
+ {
+ WindowState = WindowState.Minimized;
+ }
+
+ private void TabButtonEnter(object sender, MouseEventArgs e)
+ {
+ ((Button)sender).Foreground = new SolidColorBrush(Colors.Gray);
+ }
+ private void TabButtonLeave(object sender, MouseEventArgs e)
+ {
+ ((Button)sender).Foreground = new SolidColorBrush(Colors.White);
+ }
+
+ private void Border_MouseDown(object sender, MouseButtonEventArgs e)
+ {
+ if (e.LeftButton == MouseButtonState.Pressed) DragMove();
+ }
+
+ private void LoadingPlaceHolder_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
+ {
+ if (LoadingPlaceHolder.Visibility == Visibility.Visible)
+ WpfAnimatedGif.ImageBehavior.GetAnimationController(LoadingPlaceHolder)?.Play();
+ else
+ WpfAnimatedGif.ImageBehavior.GetAnimationController(LoadingPlaceHolder)?.Pause();
+ }
+ }
+}
diff --git a/ValorantCC/SubWindow/UpdateWindow.xaml.cs b/ValorantCC/SubWindow/UpdateWindow.xaml.cs
index 0babd2d..0566521 100644
--- a/ValorantCC/SubWindow/UpdateWindow.xaml.cs
+++ b/ValorantCC/SubWindow/UpdateWindow.xaml.cs
@@ -19,13 +19,12 @@ private void UIChange(object sender, EventArgs e)
Messagelbl.Content = Updater.Message;
progressBar1.Value = Updater.ProgressPercentage;
- switch (Updater.State)
+ switch (Updater.ShortState)
{
- case UpdaterState.Canceled:
- case UpdaterState.InstallFailed:
+ case UpdaterShortState.Canceled:
OKbtn.Visibility = Visibility.Visible;
break;
- case UpdaterState.Installed:
+ case UpdaterShortState.Installed:
Process.Start(Updater.ProgramFileName);
Application.Current.Shutdown();
break;
diff --git a/ValorantCC/SubWindow/src/CreateRender.cs b/ValorantCC/SubWindow/src/CreateRender.cs
new file mode 100644
index 0000000..38c299c
--- /dev/null
+++ b/ValorantCC/SubWindow/src/CreateRender.cs
@@ -0,0 +1,155 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+using System.Windows.Media;
+using ValorantCC.src;
+
+namespace ValorantCC
+{
+ public static class CreateRender
+ {
+ enum ButtonType
+ {
+ Share,
+ Details,
+ Apply
+ }
+
+ static Style style;
+ static Random rand = new Random();
+ static BrushConverter bc = new BrushConverter();
+ static List imageSources = new List();
+ static ImageBrush RandomBG => imageSources[rand.Next(0, imageSources.Count - 1)];
+
+ static CreateRender()
+ {
+ ResourceDictionary res = (ResourceDictionary)Application.LoadComponent(new Uri("Resources/BGdictionary.xaml", UriKind.Relative));
+ for (int i = 0; i < res.Count; i++)
+ imageSources.Add(new ImageBrush((ImageSource)res["crosshairBG" + i]));
+ }
+
+ public static async Task GenerateRender(this ProfilesWindow profilesWindow, PublicProfile profile)
+ {
+ // This will be changed and will be replaced with more efficient method of rendering multiple settings.
+
+ // Main border
+ Border template = new Border()
+ {
+ Background = RandomBG,
+ CornerRadius = new CornerRadius(7, 7, 25, 25),
+ MinHeight = 95,
+ MaxHeight = 95,
+ MinWidth = 300,
+ MaxWidth = 300,
+ Margin = new Thickness(5, 10, 0, 0)
+ };
+ // First Grid and defintions
+
+ Grid Grid0 = new Grid();
+ ColumnDefinition gridCol0 = new ColumnDefinition();
+ ColumnDefinition gridCol1 = new ColumnDefinition();
+ ColumnDefinition gridCol2 = new ColumnDefinition();
+ RowDefinition gridRow0 = new RowDefinition() { Height = new GridLength(2.5, GridUnitType.Star) };
+ RowDefinition gridRow1 = new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) };
+ Grid0.ColumnDefinitions.Add(gridCol0);
+ Grid0.ColumnDefinitions.Add(gridCol1);
+ Grid0.ColumnDefinitions.Add(gridCol2);
+ Grid0.RowDefinitions.Add(gridRow0);
+ Grid0.RowDefinitions.Add(gridRow1);
+ // General button background
+ Border rect = new()
+ {
+ Background = (Brush)bc.ConvertFromString("#282A36"),
+ CornerRadius = new CornerRadius(0, 0, 7, 7),
+ MinWidth = 300,
+ MaxWidth = 300,
+ MinHeight = 27,
+ MaxHeight = 27,
+ };
+ Grid.SetColumn(rect, 0);
+ Grid.SetRow(rect, 1);
+ Grid.SetColumnSpan(rect, 3);
+
+ Label ownerName = new Label()
+ {
+ Content = profile.owner,
+ VerticalAlignment = VerticalAlignment.Bottom,
+ HorizontalAlignment = HorizontalAlignment.Right,
+ Foreground = Brushes.White
+ };
+ Grid.SetColumn(ownerName, 2);
+ Grid.SetRow(ownerName, 0);
+
+ style = (Style)profilesWindow.FindResource("MahApps.Styles.Button.MetroWindow.Base");
+
+ Button shareButton = ButtonType.Share.Generate(profile.sharecode);
+ shareButton.Click += profilesWindow.shareBtnClicked;
+ shareButton.Foreground = Brushes.White;
+
+ Button detailsButton = ButtonType.Details.Generate(profile.ID.ToString());
+ detailsButton.Click += profilesWindow.detailsBtnClicked;
+ detailsButton.Foreground = Brushes.White;
+
+ Button applyButton = ButtonType.Apply.Generate(profile.ID.ToString());
+ applyButton.Click += profilesWindow.applyBtnClicked;
+ applyButton.Foreground = Brushes.White;
+
+ Grid.SetColumn(shareButton, 0);
+ Grid.SetRow(shareButton, 1);
+ Grid.SetColumn(detailsButton, 1);
+ Grid.SetRow(detailsButton, 1);
+ Grid.SetColumn(applyButton, 2);
+ Grid.SetRow(applyButton, 1);
+ Grid0.Children.Add(rect);
+ Grid0.Children.Add(ownerName);
+ Grid0.Children.Add(shareButton);
+ Grid0.Children.Add(detailsButton);
+ Grid0.Children.Add(applyButton);
+ ProfileSettings cross = profile.settings.Primary;
+
+ Crosshair_Parser.Generate(0, Grid0, cross);
+ if (!profile.settings.bUsePrimaryCrosshairForADS)
+ cross = profile.settings.aDS;
+ Crosshair_Parser.Generate(1, Grid0, cross);
+ Crosshair_Parser.Generate(2, Grid0, profile.settings.Sniper);
+ template.Child = Grid0;
+ await Task.Delay(1);
+ return template;
+ }
+
+ private static Button Generate(this ButtonType btntype, string namedata)
+ {
+ Button button = new Button()
+ {
+ Style = style,
+ Background = (Brush)bc.ConvertFromString("#4648BF"),
+ Margin = new Thickness() { Bottom = 0, Top = 2, Left = 5, Right = 5 },
+ FontSize = 11,
+ Height = 22,
+ FontWeight = FontWeights.Bold,
+ Cursor = Cursors.Hand,
+ };
+
+ switch (btntype)
+ {
+ case ButtonType.Share:
+ button.Content = "Share";
+ button.Name = $"A_{namedata}_shareBtn";
+ break;
+ case ButtonType.Details:
+ button.Content = "Details";
+ button.Name = $"A_{namedata}_detailsBtn";
+ break;
+ case ButtonType.Apply:
+ button.Content = "Apply";
+ button.Name = $"A_{namedata}_applyBtn";
+ break;
+ }
+
+ return button;
+ }
+ }
+}
diff --git a/ValorantCC/ValorantCC.csproj b/ValorantCC/ValorantCC.csproj
index 27d4848..443bd4f 100644
--- a/ValorantCC/ValorantCC.csproj
+++ b/ValorantCC/ValorantCC.csproj
@@ -2,7 +2,7 @@
WinExe
- net5.0-windows
+ net6.0-windows
true
Weedeej
N/A
@@ -14,13 +14,15 @@
false
- 2.6.10
+ 3.0.0
false
+
+
@@ -29,6 +31,7 @@
+
@@ -37,6 +40,12 @@
PreserveNewest
+
+
+ PreserveNewest
+
+
+ PreserveNewest
PreserveNewest
@@ -56,13 +65,22 @@
PreserveNewest
+
+ PreserveNewest
+
+
+
+ PreserveNewest
+
-
+
+
+
-
-
+
+
@@ -70,26 +88,19 @@
-
- References\Xceed.Wpf.AvalonDock.dll
-
-
- References\Xceed.Wpf.AvalonDock.Themes.Aero.dll
-
-
- References\Xceed.Wpf.Toolkit.dll
-
+ <_DeploymentManifestIconFile Remove="Resources\vtools-colored.ico" />
- <_DeploymentManifestIconFile Remove="Resources\vtools-colored.ico" />
+
+ Never
+
-
+
PreserveNewest
-
-
+
diff --git a/ValorantCC/src/API.cs b/ValorantCC/src/API.cs
new file mode 100644
index 0000000..602306d
--- /dev/null
+++ b/ValorantCC/src/API.cs
@@ -0,0 +1,140 @@
+using Newtonsoft.Json;
+using RestSharp;
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Utilities;
+using ValorantCC.src.Community;
+
+namespace ValorantCC
+{
+ public struct SetCallResponse
+ {
+ public bool success { get; set; }
+ public string message { get; set; }
+ }
+
+ public struct FetchResponse
+ {
+ public bool success { get; set; }
+ public List data { get; set; }
+ public string message { get; set; }
+ }
+
+ public struct ShareableProfile
+ {
+ public String shareCode { get; set; }
+ public String settings { get; set; }
+ public bool shareable { get; set; }
+ public String displayName { get; set; }
+ }
+
+ public partial class Payload
+ {
+ public String settings { get; set; }
+ public bool shareable { get; set; }
+ public String sharecode { get; set; }
+ }
+ public class API
+ {
+ private static AuthTokens AuthTokens;
+ private static RestClient client = new RestClient("https://vtools-next.vercel.app/api");
+
+ public CrosshairProfile profile;
+ public bool Shareable;
+ public API(AuthTokens Tokens, CrosshairProfile TargetProfile, int ActionInt, bool isShareable)
+ {
+ AuthTokens = Tokens;
+ profile = TargetProfile;
+ Shareable = isShareable;
+ }
+
+ public async Task Fetch(String sharecode = null)
+ {
+ RestRequest request;
+ if (sharecode != null)
+ request = new RestRequest($"/sharecode/{sharecode}", Method.Get);
+ else
+ request = new RestRequest("/profiles", Method.Get);
+
+ RestResponse response = await client.ExecuteAsync(request);
+ if (!response.IsSuccessful && response.StatusCode != System.Net.HttpStatusCode.NotFound)
+ {
+ Utils.Log(response.Content.ToString());
+ return new FetchResponse() { success = false };
+ }
+ if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
+ {
+ return new FetchResponse() { success = true, data = new List() };
+ }
+
+ return new FetchResponse()
+ {
+ success = true,
+ data = JsonConvert.DeserializeObject>(response.Content)
+ };
+ }
+
+ public async Task ObtainSelfSaved()
+ {
+ RestRequest request = new RestRequest($"/profiles/{AuthTokens.Subject}/fetch", Method.Get);
+
+ RestResponse response = await client.ExecuteAsync(request);
+ if (!response.IsSuccessful && response.StatusCode != System.Net.HttpStatusCode.NotFound)
+ {
+ Utils.Log(response.Content.ToString());
+ return new FetchResponse() { success = false, message = response.Content.ToString() };
+ }
+ if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
+ return new FetchResponse() { success = true, message = response.Content.ToString() };
+
+ return new FetchResponse()
+ {
+ success = true,
+ data = new List() { JsonConvert.DeserializeObject(response.Content) }
+ };
+ }
+
+ public async Task Set()
+ {
+ Payload payload = new Payload()
+ {
+ settings = JsonConvert.SerializeObject(profile),
+ shareable = Shareable,
+ sharecode = SCGen.GenerateShareCode(AuthTokens.Subject)
+ };
+ RestRequest request = new RestRequest($"/profiles/{AuthTokens.Subject}/set", Method.Put) { RequestFormat = DataFormat.Json };
+ request.AddJsonBody(payload);
+ request.AddOrUpdateHeader("Authorization", $"Bearer {AuthTokens.AccessToken}"); // Pass to server so nobody can set somebody's saved profile.
+ RestResponse response = await client.ExecuteAsync(request);
+ if (!response.IsSuccessful)
+ {
+ Utils.Log(response.Content.ToString());
+ int retry = 0;
+ while (response.StatusCode == System.Net.HttpStatusCode.Conflict)
+ {
+ await Task.Delay(500);
+ if (response.StatusCode != System.Net.HttpStatusCode.Conflict) break;
+ // Retry until 5 retries or removed the conflict.
+ payload.sharecode = SCGen.GenerateShareCode(AuthTokens.Subject);
+ request = new RestRequest($"/profiles/{AuthTokens.Subject}/set", Method.Put) { RequestFormat = DataFormat.Json };
+ request.AddJsonBody(payload);
+ request.AddOrUpdateHeader("Authorization", $"Bearer {AuthTokens.AccessToken}");
+ response = await client.ExecuteAsync(request);
+ retry++;
+ Utils.Log($"Conflict removal retry: {retry}: {response.Content}");
+ if (retry >= 5) break;
+ }
+ if (response.StatusCode != System.Net.HttpStatusCode.Conflict)
+ {
+ Utils.Log(response.Content.ToString());
+ return new SetCallResponse() { success = false, message = response.Content.ToString() };
+ }
+ Utils.Log($"Failure to remove the conflict. Sharecode: {payload.sharecode} | {response.Content}");
+ return new SetCallResponse() { success = false, message = response.Content.ToString() };
+ }
+ return new SetCallResponse() { success = true, message = payload.sharecode };
+ }
+
+ }
+}
diff --git a/ValorantCC/src/Auth.cs b/ValorantCC/src/Auth.cs
index 1ce2a91..711dadd 100644
--- a/ValorantCC/src/Auth.cs
+++ b/ValorantCC/src/Auth.cs
@@ -1,9 +1,9 @@
using Newtonsoft.Json;
+using RestSharp;
using System;
using System.IO;
-using System.Net;
using System.Text;
-using Utilities;
+using System.Threading.Tasks;
namespace ValorantCC
{
public partial class AuthTokens
@@ -51,50 +51,45 @@ public partial class VersionData
}
public class AuthObj
{
- public AuthResponse StartAuth(bool wait = false)
+ LockfileData LocalCredentials;
+ static RestClient client = new RestClient(new RestClientOptions() { RemoteCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) => true });
+ public async Task StartAuth()
{
string LockfilePath = Environment.GetEnvironmentVariable("LocalAppData") + "\\Riot Games\\Riot Client\\Config\\lockfile";
- if (wait)
- {
- Utils.Log("Waiting for Lockfile");
-
- bool LockfileExists = CheckLockFile(LockfilePath);
- while (!LockfileExists)
- {
- LockfileExists = CheckLockFile(LockfilePath);
- }
- }
-
- LockfileData LocalCredentials = ObtainLockfileData(LockfilePath);
+ LocalCredentials = ObtainLockfileData(LockfilePath);
if (!LocalCredentials.Success) return new AuthResponse() { Success = false, Response = "Please login to Riot Client or Start Valorant." };
- AuthTokens Tokens = ObtainAuthTokens(LocalCredentials.Basic, LocalCredentials.Port);
+ AuthTokens Tokens = await ObtainAuthTokens();
if (!Tokens.Success) return new AuthResponse() { Success = false, Response = "Please login to Riot Client or Start Valorant." };
- return new AuthResponse() { Success = true, AuthTokens = Tokens, LockfileData = LocalCredentials, Version = GetVersion() };
+ return new AuthResponse() { Success = true, AuthTokens = Tokens, LockfileData = LocalCredentials, Version = await GetVersion() };
}
- private static bool CheckLockFile(string LockfilePath)
+ public static bool CheckLockFile(string LockfilePath)
{
return File.Exists(LockfilePath);
}
- private static LockfileData ObtainLockfileData(string LockfilePath)
+ public static LockfileData ObtainLockfileData(string LockfilePath)
{
string LockfileRaw;
try
{
- Utils.Log("Trying to open Lockfile");
- FileStream File = new FileStream(LockfilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
- StreamReader Reader = new StreamReader(File, Encoding.UTF8);
- LockfileRaw = Reader.ReadToEnd();
- File.Close();
- Reader.Close();
+ Utilities.Utils.Log("Trying to open Lockfile");
+ using (FileStream File = new FileStream(LockfilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
+ {
+ using (StreamReader Reader = new StreamReader(File, Encoding.UTF8))
+ {
+ LockfileRaw = (String)Reader.ReadToEnd().Clone();
+ File.Close();
+ Reader.Close();
+ }
+ }
}
catch (FileNotFoundException)
{
- Utils.Log("Lockfile not found");
+ Utilities.Utils.Log("Lockfile not found");
return new LockfileData();
}
@@ -111,39 +106,29 @@ private static LockfileData ObtainLockfileData(string LockfilePath)
};
}
- private AuthTokens ObtainAuthTokens(string Basic, int port)
+ private async Task ObtainAuthTokens()
{
- Utils.Log("Creating Auth Request");
+ Utilities.Utils.Log("Creating Auth Request");
+ RestRequest request = new RestRequest($"https://127.0.0.1:{LocalCredentials.Port}/entitlements/v1/token", Method.Get);
+ request.AddHeader("Authorization", $"Basic {LocalCredentials.Basic}");
- HttpWebRequest request = HttpWebRequest.CreateHttp($"https://127.0.0.1:{port}/entitlements/v1/token");
- request.Method = "GET";
- request.Headers.Add("Authorization", $"Basic {Basic}");
- request.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
- HttpWebResponse resp;
- try
- {
- Utils.Log("Sending Auth Request");
- resp = (HttpWebResponse)request.GetResponse();
- }
- catch (WebException ex)
- {
- Utils.Log($"Auth Error {ex}");
- return new AuthTokens();
- }
+ RestResponse response = await client.ExecuteAsync(request);
+ if (!response.IsSuccessful) return new AuthTokens();
- StreamReader sr = new StreamReader(resp.GetResponseStream());
- AuthTokens tokens = JsonConvert.DeserializeObject(sr.ReadToEnd());
+ AuthTokens tokens = JsonConvert.DeserializeObject(response.Content.ToString());
tokens.Success = true;
return tokens;
}
- private static string GetVersion()
+ private async static Task GetVersion()
{
- HttpWebRequest request = HttpWebRequest.CreateHttp("https://valorant-api.com/v1/version");
- request.Method = "GET";
- HttpWebResponse response = (HttpWebResponse)request.GetResponse();
- StreamReader sr = new StreamReader(response.GetResponseStream());
- VersionResponse RespData = JsonConvert.DeserializeObject(sr.ReadToEnd());
+ Utilities.Utils.Log("Obtaining Client Version info");
+ RestRequest request = new RestRequest("https://valorant-api.com/v1/version", Method.Get);
+
+ RestResponse response = await client.ExecuteAsync(request);
+ if (!response.IsSuccessful) return "0.0.0";
+
+ VersionResponse RespData = JsonConvert.DeserializeObject(response.Content.ToString());
return RespData.Data.RiotClientVersion;
}
}
diff --git a/ValorantCC/src/BackgroundAuth.cs b/ValorantCC/src/BackgroundAuth.cs
new file mode 100644
index 0000000..3e26401
--- /dev/null
+++ b/ValorantCC/src/BackgroundAuth.cs
@@ -0,0 +1,103 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Media;
+
+namespace ValorantCC
+{
+ class BackgroundAuth
+ {
+ MainWindow main = (MainWindow)Application.Current.MainWindow;
+ Processor processor;
+ public BackgroundAuth(Processor processor1)
+ {
+ processor = processor1;
+ }
+ public async void LoopCheck()
+ {
+ string LockfilePath = Environment.GetEnvironmentVariable("LocalAppData") + "\\Riot Games\\Riot Client\\Config\\lockfile"; //Copy pasted from Auth.cs because why not?
+ bool lockfilexists = false;
+ main.ch_display.Visibility = Visibility.Collapsed;
+ main.buttons_group.Visibility = Visibility.Collapsed;
+ main.controls_group.Visibility = Visibility.Collapsed;
+ while (true)
+ {
+ if (AuthObj.CheckLockFile(LockfilePath) && !lockfilexists)
+ {
+ main.StatusTxt.Foreground = Brushes.Yellow;
+ main.StatusTxt.Text = "Waiting for session. . .";
+ lockfilexists = true;
+ }
+ if (!await LoginFlagExists())
+ {
+ await Task.Delay(1500);
+ continue;
+ }
+ if (lockfilexists && AuthObj.ObtainLockfileData(LockfilePath).Success)
+ {
+ main.StatusTxt.Text = "Logging in. . .";
+ AuthResponse AuthResponse = await processor.Login();
+ main.DataProcessor = processor;
+ main.LoggedIn = AuthResponse.Success;
+ if (!main.LoggedIn)
+ {
+ main.StatusTxt.Text = "Failed. Please login to Riot Client or Start Valorant.";
+ await Task.Delay(1500);
+ continue;
+ }
+ main.profiles.ItemsSource = processor.ProfileNames;
+ main.profiles.SelectedIndex = processor.CurrentProfile;
+ main.profiles.IsReadOnly = false;
+ main.ValCCAPI = new API(AuthResponse.AuthTokens, main.SelectedProfile, 2, (main.chkbxShareable.IsChecked ?? false));
+
+ main.DotTxt.Foreground = Brushes.Lime;
+ main.StatusTxt.Foreground = Brushes.Lime;
+ Utilities.Utils.MessageText(Utilities.Utils.LoginResponse(processor), Brushes.Lime);
+ main.StatusTxt.Text = "Logged In!";
+
+ main.UpdateLayout();
+ double OriginalHeight = main.Height;
+
+ main.ch_display.Visibility = Visibility.Visible;
+ main.buttons_group.Visibility = Visibility.Visible;
+ main.controls_group.Visibility = Visibility.Visible;
+ main.chkbxShareable.Visibility = Visibility.Visible;
+
+ main.spinner.Visibility = Visibility.Collapsed;
+ main.spinner.Spin = false;
+ main.UpdateLayout();
+ Trace.WriteLine(main.Height + " || " + OriginalHeight);
+ main.Top = main.Top - (main.Height - OriginalHeight) / 2;
+
+ return;
+ }
+ await Task.Delay(1500);
+ }
+ }
+
+ public async static Task LoginFlagExists()
+ {
+ DirectoryInfo LogDir = new DirectoryInfo(Environment.GetEnvironmentVariable("LocalAppData") + "\\Riot Games\\Riot Client\\Logs\\Riot Client Logs");
+ var log = LogDir.GetFiles().OrderByDescending(f => f.LastWriteTime).First();
+
+ string content;
+ using (FileStream fileStream = File.Open(log.FullName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
+ {
+ using (StreamReader sr = new StreamReader(fileStream))
+ {
+ content = (String)sr.ReadToEnd().Clone();
+ }
+ }
+ bool t = false;
+ if (content.Contains("riot-messaging-service: State is now Connected"))
+ {
+ t = true;
+ }
+ await Task.Delay(1);
+ return t;
+ }
+ }
+}
diff --git a/ValorantCC/src/Binder.cs b/ValorantCC/src/Binder.cs
index ee9a457..9a8ca5b 100644
--- a/ValorantCC/src/Binder.cs
+++ b/ValorantCC/src/Binder.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
namespace ValorantCC
{
public partial class Actionmapping
@@ -72,12 +73,17 @@ public partial class SniperSettings
public float CenterDotOpacity { get; set; }
public bool bDisplayCenterDot { get; set; }
}
- public partial class CrosshairColor
+ public partial class CrosshairColor : ICloneable
{
public byte R { get; set; }
public byte G { get; set; }
public byte B { get; set; }
public byte A { get; set; }
+
+ public object Clone()
+ {
+ throw new NotImplementedException();
+ }
}
public partial class LineSettings
@@ -102,14 +108,14 @@ public partial class ProfileList
public partial class Data
{
- public Actionmapping[] actionMappings { get; set; }
- public object[] axisMappings { get; set; }
- public Boolsetting[] boolSettings { get; set; }
- public Floatsetting[] floatSettings { get; set; }
- public Intsetting[] intSettings { get; set; }
+ public List actionMappings { get; set; }
+ public List