From 675455a990ed12d60a3c1eb8044d6cd4f3325596 Mon Sep 17 00:00:00 2001 From: AveryMadness Date: Tue, 23 Jan 2024 14:16:16 -0700 Subject: [PATCH] buncha shit --- Partypacker/INIFile.cs | 275 +++++++++++++++++++++++++++++++++ Partypacker/MainWindow.xaml | 13 +- Partypacker/MainWindow.xaml.cs | 91 ++++++++++- Partypacker/global.json | 6 + 4 files changed, 375 insertions(+), 10 deletions(-) create mode 100644 Partypacker/INIFile.cs create mode 100644 Partypacker/global.json diff --git a/Partypacker/INIFile.cs b/Partypacker/INIFile.cs new file mode 100644 index 0000000..d7e2af0 --- /dev/null +++ b/Partypacker/INIFile.cs @@ -0,0 +1,275 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.IO; + +namespace Partypacker +{ + public class INIFile + { + private string _File; + + /// + /// Call the constructor creates a new object of the INIFile class to work with INI files. + /// + /// Name of INI file, which you want to access. + /// Specifies whether the INI file should be created if it does not exist. + public INIFile(string file, bool createFile = false) + { + if (createFile == true && File.Exists(file) == false) + { + FileInfo fileInfo = new FileInfo(file); + FileStream fileStream = fileInfo.Create(); + fileStream.Close(); + } + _File = file; + } + + #region Public Methods + + /// + /// Removes all comments and empty lines from a complete section and returns the sections. + /// This method is not case-sensitive. + /// The return value does not contain any spaces at the beginning or at the end of a line. + /// + /// Name of the requested section. + /// Specifies whether comments should also be returned. + /// Returns the whole section. + public List GetSection(string section, bool includeComments = false) + { + section = CheckSection(section); + + List completeSection = new List(); + bool sectionStart = false; + + string[] fileArray = File.ReadAllLines(_File); + + foreach (var item in fileArray) + { + if (item.Length <= 0) continue; + + // Beginning of section. + if (item.Replace(" ", "").ToLower() == section) + { + sectionStart = true; + } + // Beginning of next section. + if (sectionStart == true && item.Replace(" ", "").ToLower() != section && item.Replace(" ", "").Substring(0, 1) == "[" && item.Replace(" ", "").Substring(item.Length - 1, 1) == "]") + { + break; + } + if (sectionStart == true) + { + // Add the entry to the List completeSection, if it is not a comment or an empty entry. + if (includeComments == false + && item.Replace(" ", "").Substring(0, 1) != ";" && !string.IsNullOrWhiteSpace(item)) + { + completeSection.Add(ReplaceSpacesAtStartAndEnd(item)); + } + if (includeComments == true && !string.IsNullOrWhiteSpace(item)) + { + completeSection.Add(ReplaceSpacesAtStartAndEnd(item)); + } + } + } + return completeSection; + } + + /// + /// The method returns a value for the associated key. + /// This method is not case-sensitive. + /// + /// Name of the requested section. + /// Name of the requested key. + /// If "true" is passed, the value will be returned in lowercase letters. + /// Returns the value for the specified key in the specified section, if available, otherwise null. + public string GetValue(string section, string key, bool convertValueToLower = false) + { + section = CheckSection(section); + key = key.ToLower(); + + List completeSection = GetSection(section); + + foreach (var item in completeSection) + { + // Continue if entry is no key. + if (!item.Contains("=") && item.Contains("[") && item.Contains("]")) continue; + + string[] keyAndValue = item.Split(new string[] { "=" }, StringSplitOptions.RemoveEmptyEntries); + if (keyAndValue[0].ToLower() == key && keyAndValue.Count() > 1) + { + if (convertValueToLower == true) + { + keyAndValue[1] = keyAndValue[1].ToLower(); + } + return keyAndValue[1]; + } + } + return null; + } + + /// + /// Set or add a value of the associated key in the specified section. + /// This method is not case-sensitive. + /// + /// Name of the section. + /// Name of the key. + /// Value to save. + /// If "true" is passed, the value will be saved in lowercase letters. + public void SetValue(string section, string key, string value, bool convertValueToLower = false) + { + section = CheckSection(section, false); + string sectionToLower = section.ToLower(); + + bool sectionFound = false; + + List iniFileContent = new List(); + + string[] fileLines = File.ReadAllLines(_File); + + // Creates a new INI file if none exists. + if (fileLines.Length <= 0) + { + iniFileContent = AddSection(iniFileContent, section, key, value, convertValueToLower); + WriteFile(iniFileContent); + return; + } + + for (int i = 0; i < fileLines.Length; i++) + { + // Possibility 1: The desired section has not (yet) been found. + if (fileLines[i].Replace(" ", "").ToLower() != sectionToLower) + { + iniFileContent.Add(fileLines[i]); + // If a section does not exist, the section will be created. + if (i == fileLines.Length - 1 && fileLines[i].Replace(" ", "").ToLower() != sectionToLower && sectionFound == false) + { + iniFileContent.Add(null); + iniFileContent = AddSection(iniFileContent, section, key, value, convertValueToLower); + break; + } + continue; + } + + + // Possibility 2 -> Desired section was found. + sectionFound = true; + + // Get the complete section in which the target key may be. + List targetSection = GetSection(sectionToLower, true); + + for (int x = 0; x < targetSection.Count; x++) + { + string[] targetKey = targetSection[x].Split(new string[] { "=" }, StringSplitOptions.None); + // When the target key is found. + if (targetKey[0].ToLower() == key.ToLower()) + { + if (convertValueToLower == true) + { + iniFileContent.Add(key + "=" + value.ToLower()); + } + else + { + iniFileContent.Add(key + "=" + value); + } + i = i + x; + break; + } + else + { + iniFileContent.Add(targetSection[x]); + // If the target key is not found, it will be created. + if (x == targetSection.Count - 1 && targetKey[0].ToLower() != key.ToLower()) + { + if (convertValueToLower == true) + { + iniFileContent.Add(key + "=" + value.ToLower()); + } + else + { + iniFileContent.Add(key + "=" + value); + } + i = i + x; + break; + } + } + } + } + + WriteFile(iniFileContent); + } + + #endregion + + #region Private Methods + + /// + /// Ensures that a section is always in the following format: [section]. + /// + /// Section to be checked for correct format. + /// Specifies whether the section should be vonverted in lower case letters. + /// Returns section in this form: [section]. + private string CheckSection(string section, bool convertToLower = true) + { + if (convertToLower == true) + { + section = section.ToLower(); + } + if (!section.StartsWith("[") && !section.EndsWith("]")) + { + section = "[" + section + "]"; + } + return section; + } + + /// + /// Removes leading and trailing spaces from sections, keys and values. + /// + /// String to be trimmed. + /// Returns the trimmed string. + private string ReplaceSpacesAtStartAndEnd(string item) + { + // If the string has a key and a value. + if (item.Contains("=") && !item.Contains("[") && !item.Contains("]")) + { + string[] keyAndValue = item.Split(new string[] { "=" }, StringSplitOptions.None); + return keyAndValue[0].Trim() + "=" + keyAndValue[1].Trim(); + } + + return item.Trim(); + } + + /// + /// Adds a new section with key value pair. + /// + /// List iniFileContent from SetValue. + /// Section to be created. + /// Key to be added. + /// Value to be added. + /// Specifies whether the key and value should be saved in lower case letters. + /// Returns the new created section with key value pair. + private List AddSection(List iniFileContent, string section, string key, string value, bool convertValueToLower) + { + if (convertValueToLower == true) + { + value = value.ToLower(); + } + + iniFileContent.Add(section); + iniFileContent.Add($"{key}={value}"); + return iniFileContent; + } + + private void WriteFile(List content) + { + StreamWriter writer = new StreamWriter(_File); + foreach (var item in content) + { + writer.WriteLine(item); + } + writer.Close(); + } + + #endregion + } +} \ No newline at end of file diff --git a/Partypacker/MainWindow.xaml b/Partypacker/MainWindow.xaml index f3a7828..c5e480d 100644 --- a/Partypacker/MainWindow.xaml +++ b/Partypacker/MainWindow.xaml @@ -31,9 +31,14 @@ - - - - + + + + + + + + + diff --git a/Partypacker/MainWindow.xaml.cs b/Partypacker/MainWindow.xaml.cs index 30be79f..3b332bd 100644 --- a/Partypacker/MainWindow.xaml.cs +++ b/Partypacker/MainWindow.xaml.cs @@ -1,12 +1,16 @@ using Newtonsoft.Json; +using Newtonsoft.Json.Linq; using Partypacker.Core; using Partypacker.Net; using System.Diagnostics; using System.Net; using System.Text; +using System.Text.RegularExpressions; using System.Web; using System.Windows; using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Media; using WatsonWebserver; namespace Partypacker @@ -22,6 +26,7 @@ namespace Partypacker static string Token; static UserDetailObject UserDetails; static Server sv; + static INIFile settings = new("settings.ini", true); public MainWindow() { @@ -37,6 +42,11 @@ namespace Partypacker } DiscordAuthURL = DiscordURL.Value; + + if (!string.IsNullOrWhiteSpace(settings.GetValue("Launcher", "token"))) + { + AutoLogin(); + } } void OnApplicationExit(object sender, ExitEventArgs e) => Proxx?.StopProxy(); @@ -47,9 +57,59 @@ namespace Partypacker Port = P; } - void OnDashboard(object sender, RoutedEventArgs e) => Process.Start(new ProcessStartInfo { UseShellExecute = true, FileName = PartypackServer.DashboardURL }); + void OnDashboard(object sender, MouseButtonEventArgs e) => Process.Start(new ProcessStartInfo { UseShellExecute = true, FileName = PartypackServer.DashboardURL + "/profile"}); - private static async Task DefaultRoute(HttpContext ctx) + private void UpdateUserUI() + { + this.Dispatcher.Invoke(() => + { + UsernameTextBlock.Text = @$"{UserDetails.GlobalName} (@{UserDetails.Username})"; + ProfilePictureImage.ImageSource = (ImageSource)new ImageSourceConverter().ConvertFromString(UserDetails.Avatar); + UsernameTextBlock.Visibility = Visibility.Visible; + PFPContainer.Visibility = Visibility.Visible; + }); + } + + void AutoLogin() + { + Token = settings.GetValue("Launcher", "token"); + UserDetails = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(Convert.FromHexString(HttpUtility.UrlDecode(settings.GetValue("Launcher", "user"))))); + UpdateUserUI(); + Dispatcher.Invoke(() => + { + LaunchButton.IsEnabled = true; + }); + ConvertLoginToLogout(); + } + + private void ConvertLoginToLogout() + { + Dispatcher.Invoke(() => + { + LoginButton.Content = "Log Out"; + LoginButton.Click -= OnLoginUsingDiscord; + LoginButton.Click += OnLogout; + }); + } + + private void OnLogout(object sender, RoutedEventArgs e) + { + this.Dispatcher.Invoke(() => + { + UsernameTextBlock.Visibility = Visibility.Hidden; + PFPContainer.Visibility = Visibility.Hidden; + UserDetails = null; + Token = ""; + settings.SetValue("Launcher", "user", ""); + settings.SetValue("Launcher", "token", ""); + + LoginButton.Content = "Log in using Discord"; + LoginButton.Click += OnLoginUsingDiscord; + LoginButton.Click -= OnLogout; + }); + } + + private async Task DefaultRoute(HttpContext ctx) { string _Token = ctx.Request.Query.Elements["token"]; string _UserDetails = ctx.Request.Query.Elements["user"]; @@ -62,20 +122,33 @@ namespace Partypacker Token = _Token; UserDetails = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(Convert.FromHexString(HttpUtility.UrlDecode(_UserDetails)))); + settings.SetValue("Launcher", "user", HttpUtility.UrlDecode(_UserDetails)); + settings.SetValue("Launcher", "token", Token); + UpdateUserUI(); + Dispatcher.Invoke(() => + { + LaunchButton.IsEnabled = true; + }); + ConvertLoginToLogout(); await ctx.Response.Send("All done! You can close this tab now."); sv.Stop(); + sv = null; } void OnLoginUsingDiscord(object sender, RoutedEventArgs e) { - Process.Start(new ProcessStartInfo { UseShellExecute = true, FileName = $"{DiscordAuthURL}&state={HttpUtility.UrlEncode(Convert.ToBase64String(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new + Process.Start(new ProcessStartInfo { UseShellExecute = true, FileName = $@"{DiscordAuthURL}&state={HttpUtility.UrlEncode(Convert.ToBase64String(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(new { Client = "PartypackerDesktop" - }))))}" }); - sv = new Server("127.0.0.1", 14968, false, DefaultRoute); - sv.Start(); + }))))}"}); + + if (sv == null) + { + sv = new Server("127.0.0.1", 14968, false, DefaultRoute); + sv.Start(); + } } void OnLaunch(object sender, RoutedEventArgs e) @@ -87,5 +160,11 @@ namespace Partypacker //Process.Start(new ProcessStartInfo { UseShellExecute = true, FileName = "com.epicgames.launcher://apps/fn%3A4fe75bbc5a674f4f9b356b5c90567da5%3AFortnite?action=launch&silent=true" }); } + + private void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e) + { + Regex regex = new Regex("[^0-9]+"); + e.Handled = regex.IsMatch(e.Text); + } } } \ No newline at end of file diff --git a/Partypacker/global.json b/Partypacker/global.json new file mode 100644 index 0000000..fd157a8 --- /dev/null +++ b/Partypacker/global.json @@ -0,0 +1,6 @@ +{ + "sdk": { + "version": "7.0.405", + "rollForward": "latestFeature" + } +} \ No newline at end of file