diff --git a/.gitignore b/.gitignore index cbbd0b5..56fdc72 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ bin/ -obj/ \ No newline at end of file +obj/ +Binaries/ \ No newline at end of file diff --git a/.vs/ProSwapperLobby/DesignTimeBuild/.dtbcache.v2 b/.vs/ProSwapperLobby/DesignTimeBuild/.dtbcache.v2 index 74fd0e0..df778dd 100644 Binary files a/.vs/ProSwapperLobby/DesignTimeBuild/.dtbcache.v2 and b/.vs/ProSwapperLobby/DesignTimeBuild/.dtbcache.v2 differ diff --git a/.vs/ProSwapperLobby/FileContentIndex/3e20a492-8c6b-4235-b99f-98a2f833a437.vsidx b/.vs/ProSwapperLobby/FileContentIndex/3e20a492-8c6b-4235-b99f-98a2f833a437.vsidx new file mode 100644 index 0000000..b512ef0 Binary files /dev/null and b/.vs/ProSwapperLobby/FileContentIndex/3e20a492-8c6b-4235-b99f-98a2f833a437.vsidx differ diff --git a/.vs/ProSwapperLobby/FileContentIndex/5d212499-49d2-4d9a-8efd-9cafe6aa303e.vsidx b/.vs/ProSwapperLobby/FileContentIndex/5d212499-49d2-4d9a-8efd-9cafe6aa303e.vsidx new file mode 100644 index 0000000..f0cea4c Binary files /dev/null and b/.vs/ProSwapperLobby/FileContentIndex/5d212499-49d2-4d9a-8efd-9cafe6aa303e.vsidx differ diff --git a/.vs/ProSwapperLobby/FileContentIndex/76e500ee-c352-41ae-a1f7-7239a2b5ad00.vsidx b/.vs/ProSwapperLobby/FileContentIndex/76e500ee-c352-41ae-a1f7-7239a2b5ad00.vsidx new file mode 100644 index 0000000..eb0e531 Binary files /dev/null and b/.vs/ProSwapperLobby/FileContentIndex/76e500ee-c352-41ae-a1f7-7239a2b5ad00.vsidx differ diff --git a/.vs/ProSwapperLobby/FileContentIndex/958a039c-2890-4bfb-b1d5-08bdc814569e.vsidx b/.vs/ProSwapperLobby/FileContentIndex/958a039c-2890-4bfb-b1d5-08bdc814569e.vsidx deleted file mode 100644 index 08fabe6..0000000 Binary files a/.vs/ProSwapperLobby/FileContentIndex/958a039c-2890-4bfb-b1d5-08bdc814569e.vsidx and /dev/null differ diff --git a/.vs/ProSwapperLobby/FileContentIndex/a4e9a90d-1c3d-4832-b015-141d7e09a157.vsidx b/.vs/ProSwapperLobby/FileContentIndex/a4e9a90d-1c3d-4832-b015-141d7e09a157.vsidx new file mode 100644 index 0000000..d097a32 Binary files /dev/null and b/.vs/ProSwapperLobby/FileContentIndex/a4e9a90d-1c3d-4832-b015-141d7e09a157.vsidx differ diff --git a/.vs/ProSwapperLobby/v17/.futdcache.v1 b/.vs/ProSwapperLobby/v17/.futdcache.v1 index 2a53a17..32de46a 100644 Binary files a/.vs/ProSwapperLobby/v17/.futdcache.v1 and b/.vs/ProSwapperLobby/v17/.futdcache.v1 differ diff --git a/.vs/ProSwapperLobby/v17/.suo b/.vs/ProSwapperLobby/v17/.suo index 00efd44..c71110b 100644 Binary files a/.vs/ProSwapperLobby/v17/.suo and b/.vs/ProSwapperLobby/v17/.suo differ diff --git a/.vs/ProSwapperLobby/v17/HierarchyCache.v1.txt b/.vs/ProSwapperLobby/v17/HierarchyCache.v1.txt index 8598bdd..a5b27be 100644 Binary files a/.vs/ProSwapperLobby/v17/HierarchyCache.v1.txt and b/.vs/ProSwapperLobby/v17/HierarchyCache.v1.txt differ diff --git a/.vs/ProSwapperLobby/v17/fileList.bin b/.vs/ProSwapperLobby/v17/fileList.bin index 2c5c8e8..6dcb163 100644 Binary files a/.vs/ProSwapperLobby/v17/fileList.bin and b/.vs/ProSwapperLobby/v17/fileList.bin differ diff --git a/.vs/ProjectEvaluation/proswapperlobby.metadata.v2 b/.vs/ProjectEvaluation/proswapperlobby.metadata.v2 index bdca8fa..667eb30 100644 Binary files a/.vs/ProjectEvaluation/proswapperlobby.metadata.v2 and b/.vs/ProjectEvaluation/proswapperlobby.metadata.v2 differ diff --git a/.vs/ProjectEvaluation/proswapperlobby.projects.v2 b/.vs/ProjectEvaluation/proswapperlobby.projects.v2 index 5dc2dad..a788993 100644 Binary files a/.vs/ProjectEvaluation/proswapperlobby.projects.v2 and b/.vs/ProjectEvaluation/proswapperlobby.projects.v2 differ diff --git a/CUE4Parse/FileProvider/Vfs/AbstractVfsFileProvider.cs b/CUE4Parse/FileProvider/Vfs/AbstractVfsFileProvider.cs index 0f8e6a9..b3247a5 100644 --- a/CUE4Parse/FileProvider/Vfs/AbstractVfsFileProvider.cs +++ b/CUE4Parse/FileProvider/Vfs/AbstractVfsFileProvider.cs @@ -23,17 +23,17 @@ public abstract class AbstractVfsFileProvider : AbstractFileProvider, IVfsFilePr public override IReadOnlyDictionary Files => _files; public override IReadOnlyDictionary FilesById => _files.byId; - protected readonly ConcurrentDictionary _unloadedVfs = new (); - public IReadOnlyCollection UnloadedVfs => (IReadOnlyCollection) _unloadedVfs.Keys; + protected readonly ConcurrentDictionary _unloadedVfs = new(); + public IReadOnlyCollection UnloadedVfs => (IReadOnlyCollection)_unloadedVfs.Keys; - private readonly ConcurrentDictionary _mountedVfs = new (); - public IReadOnlyCollection MountedVfs => (IReadOnlyCollection) _mountedVfs.Keys; + private readonly ConcurrentDictionary _mountedVfs = new(); + public IReadOnlyCollection MountedVfs => (IReadOnlyCollection)_mountedVfs.Keys; - private readonly ConcurrentDictionary _keys = new (); + private readonly ConcurrentDictionary _keys = new(); public IReadOnlyDictionary Keys => _keys; - protected readonly ConcurrentDictionary _requiredKeys = new (); - public IReadOnlyCollection RequiredKeys => (IReadOnlyCollection) _requiredKeys.Keys; + protected readonly ConcurrentDictionary _requiredKeys = new(); + public IReadOnlyCollection RequiredKeys => (IReadOnlyCollection)_requiredKeys.Keys; public IoGlobalData? GlobalData { get; private set; } @@ -109,14 +109,14 @@ public async Task MountAsync() } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public int SubmitKey(FGuid guid, FAesKey key) => SubmitKeys(new Dictionary {{ guid, key }}); + public int SubmitKey(FGuid guid, FAesKey key) => SubmitKeys(new Dictionary { { guid, key } }); [MethodImpl(MethodImplOptions.AggressiveInlining)] public int SubmitKeys(IEnumerable> keys) => SubmitKeysAsync(keys).Result; [MethodImpl(MethodImplOptions.AggressiveInlining)] public async Task SubmitKeyAsync(FGuid guid, FAesKey key) => - await SubmitKeysAsync(new Dictionary {{ guid, key }}).ConfigureAwait(false); + await SubmitKeysAsync(new Dictionary { { guid, key } }).ConfigureAwait(false); public async Task SubmitKeysAsync(IEnumerable> keys) { diff --git a/Data/API.cs b/Data/API.cs index 532d70e..4841178 100644 --- a/Data/API.cs +++ b/Data/API.cs @@ -5,7 +5,10 @@ public class API public class Rootobject { public bool Disable { get; set; } + public string DisableMessage { get; set; } public long DiscordID { get; set; } + public int KeyLifetime { get; set; } } + } } diff --git a/LobbyAPI.json b/LobbyAPI.json index ef6a447..14c1515 100644 --- a/LobbyAPI.json +++ b/LobbyAPI.json @@ -1,4 +1,6 @@ { "Disable": false, - "DiscordID": 703033424541384784 + "DisableMessage": "Hello World", + "DiscordID": 703033424541384784, + "KeyLifetime": 172800 } \ No newline at end of file diff --git a/Pages/Index.razor b/Pages/Index.razor index 08208e3..1d48156 100644 --- a/Pages/Index.razor +++ b/Pages/Index.razor @@ -11,46 +11,3 @@ Select one of the tabs to start swapping!
- - -@code { - - - protected override void OnInitialized() - { - base.OnInitialized(); - - using (WebClient wc = new()) - { - string data = wc.DownloadString("https://pro-swapper.github.io/api/LobbyAPI.json"); - - var apiresp = JsonConvert.DeserializeObject(data); - - if (apiresp.Disable == true) - { - Process.GetCurrentProcess().Kill(); - } - - apiresp.DiscordID = 703033424541384784; - - Services.MainService.DiscordWidgetAPI = JsonConvert.DeserializeObject(wc.DownloadString($"https://discord.com/api/guilds/{apiresp.DiscordID}/widget.json")); - } - - ProSwapperLobby.DiscordRPC.InitializeRPC(); - - Directory.CreateDirectory(Services.MainService.ProSwapperFolder + "\\.Config"); - MainService.InitConfig(); - - Console.Clear(); - Console.Title = "Pro Swapper Lobby | Made by Kye#5000"; - Console.ForegroundColor = ConsoleColor.Red; - Console.WriteLine("Please do not close this window when using Pro Swapper or the website will not work"); - Console.WriteLine(string.Empty); - Console.WriteLine(string.Empty); - Console.ForegroundColor = ConsoleColor.Blue; - Console.WriteLine($"Pro Swapper Lobby is currently running on http://localhost:6969, if you need any help please ask for help on the Pro Swapper Discord server: {Services.MainService.DiscordWidgetAPI.instant_invite}"); - Console.WriteLine(string.Empty); - Console.WriteLine(string.Empty); - Console.WriteLine($"If you have paid for this software, you have been scammed. It is free to download at {Services.MainService.DiscordWidgetAPI.instant_invite} and is also available on GitHub: https://github.com/Pro-Swapper"); - } -} \ No newline at end of file diff --git a/Pages/About.razor b/Pages/Settings.razor similarity index 78% rename from Pages/About.razor rename to Pages/Settings.razor index 707ab6c..a627090 100644 --- a/Pages/About.razor +++ b/Pages/Settings.razor @@ -1,18 +1,23 @@ -@using static Services.MainService +@page "/settings" +@namespace ProSwapperLobby +@using System.Diagnostics +@using static Services.MainService -@page "/about" -

About

+

Settings

-
    -
  • Current AES Key: @CurrentConfig.aesKey
  • + + +
      +
    • Current AES Key: @CurrentConfig.aesKey
    • Current Installed Fortnite Version: @CurrentConfig.CurrentInstalledFortniteVersion
    • Current Live Fortnite Version: @CurrentConfig.CurrentLiveFortniteVersion
    • Fortnite Up To Date: @FnUpdated
    - - +
    + +

    Developer(s)

    @@ -137,6 +142,12 @@ @code { - private bool FnUpdated = CurrentConfig.CurrentLiveFortniteVersion == CurrentConfig.CurrentInstalledFortniteVersion; - + private bool FnUpdated => CurrentConfig.CurrentLiveFortniteVersion.Contains(CurrentConfig.CurrentInstalledFortniteVersion); + + private void LaunchFortnite() + { + Process webProcess = new Process(); + webProcess.StartInfo = new ProcessStartInfo() { UseShellExecute = true, FileName = "com.epicgames.launcher://apps/fn:4fe75bbc5a674f4f9b356b5c90567da5:Fortnite?action=launch&silent=false" }; + webProcess.Start(); + } } diff --git a/ProSwapperLobby - Backup.csproj b/ProSwapperLobby - Backup.csproj deleted file mode 100644 index c14852a..0000000 --- a/ProSwapperLobby - Backup.csproj +++ /dev/null @@ -1,33 +0,0 @@ - - - - net6.0-windows - disable - enable - True - x64 - 1.0 - 1.0 - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ProSwapperLobby.csproj b/ProSwapperLobby.csproj index 001a22a..1a63202 100644 --- a/ProSwapperLobby.csproj +++ b/ProSwapperLobby.csproj @@ -1,4 +1,4 @@ - + net6.0-windows @@ -6,21 +6,28 @@ enable True x64 - 1.0.1.0 - 1.0.1.0 + 2.0.0.0 + 2.0.0.0 The BEST Fortnite lobby swapper Pro Swapper 2022 http://proswapper.xyz Exe - ProSwapperLobby.ico + bin\ + + + + + + + - + diff --git a/ProSwapperLobby.sln b/ProSwapperLobby.sln index 33936ed..4760729 100644 --- a/ProSwapperLobby.sln +++ b/ProSwapperLobby.sln @@ -5,6 +5,8 @@ VisualStudioVersion = 17.0.32014.148 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProSwapperLobby", "ProSwapperLobby.csproj", "{11824F3D-DAAF-4FB9-8276-67077661C328}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProSwapperLobby.Client", "..\ProSwapperLobby.Client\ProSwapperLobby.Client.csproj", "{551EBD94-FFDD-4A13-81C0-82A919AA0F82}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -15,6 +17,10 @@ Global {11824F3D-DAAF-4FB9-8276-67077661C328}.Debug|Any CPU.Build.0 = Debug|Any CPU {11824F3D-DAAF-4FB9-8276-67077661C328}.Release|Any CPU.ActiveCfg = Release|Any CPU {11824F3D-DAAF-4FB9-8276-67077661C328}.Release|Any CPU.Build.0 = Release|Any CPU + {551EBD94-FFDD-4A13-81C0-82A919AA0F82}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {551EBD94-FFDD-4A13-81C0-82A919AA0F82}.Debug|Any CPU.Build.0 = Debug|Any CPU + {551EBD94-FFDD-4A13-81C0-82A919AA0F82}.Release|Any CPU.ActiveCfg = Release|Any CPU + {551EBD94-FFDD-4A13-81C0-82A919AA0F82}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Program.cs b/Program.cs index 8ecd34d..fcc1d19 100644 --- a/Program.cs +++ b/Program.cs @@ -1,6 +1,7 @@ using Blazored.Toast; using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Web; +using Newtonsoft.Json; using ProSwapperLobby.Data; using ProSwapperLobby.Services; using System.Diagnostics; @@ -8,10 +9,17 @@ public class Program { + private const string ClientExe = "ProSwapperLobby.Client.exe"; + private static void OpenUrl(string url) + { + Process webProcess = new Process(); + webProcess.StartInfo = new ProcessStartInfo() { UseShellExecute = true, FileName = url }; + webProcess.Start(); + } public static void Main(string[] args) { #if RELEASE - if (!File.Exists("aspnetcorev2_inprocess.dll")) + if (!File.Exists(ClientExe)) { Console.Clear(); Console.WriteLine("Please extract Pro Swapper Lobby.zip to a folder instead of doubling clicking it inside a zipping program."); @@ -21,14 +29,13 @@ public static void Main(string[] args) } #endif +#if DEBUG + args = new string[] { "http://localhost:6969/" }; - const string url = "http://localhost:6969"; - - ProcessStartInfo info = new ProcessStartInfo(); - info.FileName = url; - info.UseShellExecute = true; +#endif - new Process() { StartInfo = info }.Start(); + //// + args = new string[] { "http://localhost:6969/" }; Process thisProc = Process.GetCurrentProcess(); Process.GetProcessesByName(thisProc.ProcessName).Where(x => x.Id != thisProc.Id).All(x => { x.Kill(); return true; }); @@ -58,10 +65,131 @@ public static void Main(string[] args) app.MapBlazorHub(); app.MapFallbackToPage("/_Host"); - app.Run(url); -#if !RELEASE + + + + + + using (HttpClient http = new()) + { + string data = http.GetStringAsync("https://pro-swapper.github.io/api/LobbyAPI.json").Result; + + MainService.ProSwapperAPI = JsonConvert.DeserializeObject(data); + + if (MainService.ProSwapperAPI.Disable == true) + { + Console.Clear(); + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("Pro Swapper is currently down: "); + Console.Write(MainService.ProSwapperAPI.DisableMessage); + Console.ReadLine(); + Process.GetCurrentProcess().Kill(); + } + + MainService.DiscordWidgetAPI = JsonConvert.DeserializeObject(http.GetStringAsync($"https://discord.com/api/guilds/{MainService.ProSwapperAPI.DiscordID}/widget.json").Result); + } + + ProSwapperLobby.DiscordRPC.InitializeRPC(); + + Directory.CreateDirectory(MainService.ProSwapperFolder + "\\.Config"); + MainService.InitConfig(); + Console.Clear(); + Console.Title = "Pro Swapper Lobby | Made by Kye#5000"; + Console.ForegroundColor = ConsoleColor.Green; + + + Console.WriteLine("Welcome to Pro Swapper Lobby!"); + Console.ForegroundColor = ConsoleColor.Cyan; + if (MainService.CurrentConfig.AskIfServerBooster == true) + { + Console.Write("Are you a server booster in the Discord server? Please type either Yes or No: "); + string IsBoosterAnswer = Console.ReadLine().ToLower(); + if (IsBoosterAnswer == "yes" || IsBoosterAnswer == "y" || IsBoosterAnswer == "ye") + { + bool IsBooster = DiscordRoleAuth.IsServerBooster(); + } + MainService.CurrentConfig.AskIfServerBooster = false; + MainService.SaveConfig(); + } + + if (MainService.CurrentConfig.OAuthToken != null) + { + bool IsBooster = DiscordRoleAuth.IsServerBooster(); + if (IsBooster) + { + OpenUrl(args[0]); + app.Run(args[0]); + } + } + +#if DEBUG + Console.WriteLine("\n\n\n[DEBUG] Current Key: " + MainService.CurrentConfig.Key); #endif - } -} + start: if (KeyService.IsValidKey(MainService.CurrentConfig.Key)) + { + Console.WriteLine("Please do not close this window when using Pro Swapper or the website will not work"); + Console.WriteLine(); + Console.WriteLine(); + Console.ForegroundColor = ConsoleColor.Blue; + Console.WriteLine($"Pro Swapper Lobby is currently running on {args[0]}, if you need any help please ask for help on the Pro Swapper Discord server: {MainService.DiscordWidgetAPI.instant_invite}"); + Console.WriteLine(); + Console.WriteLine(); + Console.WriteLine($"If you have paid for this software, you have been scammed. It is free to download at {MainService.DiscordWidgetAPI.instant_invite} and is also available on GitHub: https://github.com/Pro-Swapper"); + OpenUrl(args[0]); + app.Run(args[0]); + } + else + { + Console.ForegroundColor = ConsoleColor.Green; + Console.WriteLine("To use Pro Swapper you must go through Linkvertise and get a " + TimeSpan.FromSeconds(MainService.ProSwapperAPI.KeyLifetime).TotalHours + " hour key"); + Thread.Sleep(1000); + Console.ForegroundColor = ConsoleColor.Cyan; + Console.WriteLine("Note: You can Server Boost the Discord server so you don't need to get a key! " + MainService.DiscordWidgetAPI.instant_invite); + + Console.WriteLine("\n\nOpening Linkvertise now..."); + Thread.Sleep(500); + KeyService.OpenKeyUrl($"https://kyeondiscord.github.io/KeySite/{KeyService.GetIPHash() + DateTime.Now.Day}"); + while (true) + { + Console.ForegroundColor = ConsoleColor.Blue; + Console.Write("Paste your key in here: "); + string key = Console.ReadLine(); + + + + if (KeyService.IsValidKey(key)) + { + MainService.CurrentConfig.Key = key; + MainService.SaveConfig(); + Console.Clear(); + goto start; + } + else if (key == "Zm9ydG5pdGViYXR0bGVwYXNzaWp1c3RzaGl0b3V0bXlhc3Nmb3J0bml0ZWJhdHRsZXBhc3Npc2hpdG91dG15ITE1MDA1NTkyMDA=") + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("[Success] Success"); + Thread.Sleep(5000); + Console.WriteLine("or so you thought."); + Thread.Sleep(5000); + Console.WriteLine("Please use linkvertise like any other person please or boost the Discord Server."); + } + else + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("[Error] Invalid Key!"); + } + } + + + } + + + + + + + + } +} \ No newline at end of file diff --git a/Properties/PublishProfiles/FolderProfile.pubxml.user b/Properties/PublishProfiles/FolderProfile.pubxml.user index b92f3e2..249b78a 100644 --- a/Properties/PublishProfiles/FolderProfile.pubxml.user +++ b/Properties/PublishProfiles/FolderProfile.pubxml.user @@ -5,6 +5,6 @@ https://go.microsoft.com/fwlink/?LinkID=208121. <_PublishTargetUrl>C:\Users\ProMa\Documents\GitHub\ProSwapperLobby\bin\Release\net6.0\publish\ - True|2022-04-05T21:54:55.9164313Z;True|2022-04-06T07:54:07.5364113+10:00;False|2022-04-06T07:53:38.1565236+10:00;True|2022-01-27T16:12:48.2518480+11:00;True|2022-01-27T16:08:05.1530175+11:00;True|2022-01-27T16:04:49.6735287+11:00;True|2022-01-27T16:04:00.0724494+11:00;True|2022-01-26T21:56:24.9835372+11:00;True|2022-01-26T21:55:45.9695963+11:00;True|2022-01-26T20:34:25.9707459+11:00;True|2022-01-26T20:32:47.6353371+11:00;True|2022-01-26T20:29:49.9377818+11:00;True|2022-01-11T16:58:41.0413373+11:00;True|2022-01-11T16:56:32.9969032+11:00;True|2022-01-11T16:39:14.1489986+11:00;True|2022-01-11T16:18:45.4436725+11:00;True|2022-01-08T22:16:13.0737159+11:00;True|2022-01-08T22:13:01.7462987+11:00;False|2022-01-08T22:12:43.2369054+11:00;False|2022-01-08T22:12:22.0086773+11:00;True|2022-01-08T22:11:09.9989797+11:00;True|2022-01-08T20:45:21.2732432+11:00;True|2022-01-03T13:02:13.0576308+11:00;True|2022-01-03T13:00:34.4633520+11:00;True|2022-01-03T12:58:27.3458382+11:00;True|2022-01-03T12:24:21.9665124+11:00;True|2022-01-03T12:16:08.1352578+11:00; + True|2022-08-02T12:17:21.3008779Z;True|2022-08-02T21:04:54.8499768+10:00;False|2022-08-02T21:02:40.6853027+10:00;False|2022-08-02T21:02:21.5340642+10:00;False|2022-08-02T21:01:42.5652819+10:00;True|2022-04-06T07:54:55.9164313+10:00;True|2022-04-06T07:54:07.5364113+10:00;False|2022-04-06T07:53:38.1565236+10:00;True|2022-01-27T16:12:48.2518480+11:00;True|2022-01-27T16:08:05.1530175+11:00;True|2022-01-27T16:04:49.6735287+11:00;True|2022-01-27T16:04:00.0724494+11:00;True|2022-01-26T21:56:24.9835372+11:00;True|2022-01-26T21:55:45.9695963+11:00;True|2022-01-26T20:34:25.9707459+11:00;True|2022-01-26T20:32:47.6353371+11:00;True|2022-01-26T20:29:49.9377818+11:00;True|2022-01-11T16:58:41.0413373+11:00;True|2022-01-11T16:56:32.9969032+11:00;True|2022-01-11T16:39:14.1489986+11:00;True|2022-01-11T16:18:45.4436725+11:00;True|2022-01-08T22:16:13.0737159+11:00;True|2022-01-08T22:13:01.7462987+11:00;False|2022-01-08T22:12:43.2369054+11:00;False|2022-01-08T22:12:22.0086773+11:00;True|2022-01-08T22:11:09.9989797+11:00;True|2022-01-08T20:45:21.2732432+11:00;True|2022-01-03T13:02:13.0576308+11:00;True|2022-01-03T13:00:34.4633520+11:00;True|2022-01-03T12:58:27.3458382+11:00;True|2022-01-03T12:24:21.9665124+11:00;True|2022-01-03T12:16:08.1352578+11:00; \ No newline at end of file diff --git a/Services/DiscordRoleAuth.cs b/Services/DiscordRoleAuth.cs new file mode 100644 index 0000000..be3af96 --- /dev/null +++ b/Services/DiscordRoleAuth.cs @@ -0,0 +1,187 @@ +using System.Collections.Specialized; +using System.Diagnostics; +using System.Net; +using System.Net.Http.Headers; +using System.Text; +using System.Text.Json; +using System.Web; + +namespace ProSwapperLobby.Services +{ + internal class GuildMember + { + + public class Root + { + public string avatar { get; set; } + public object communication_disabled_until { get; set; } + public int flags { get; set; } + public bool is_pending { get; set; } + public DateTime joined_at { get; set; } + public string nick { get; set; } + public bool pending { get; set; } + public object premium_since { get; set; } + public string[] roles { get; set; } + public User user { get; set; } + public bool mute { get; set; } + public bool deaf { get; set; } + } + + public class User + { + public string id { get; set; } + public string username { get; set; } + public string avatar { get; set; } + public object avatar_decoration { get; set; } + public string discriminator { get; set; } + public int public_flags { get; set; } + } + + } + + public class TokenResponse + { + public class Root + { + public string access_token { get; set; } + public int expires_in { get; set; } + public string refresh_token { get; set; } + public string scope { get; set; } + public string token_type { get; set; } + } + } + + public class DiscordRoleAuth + { + //Change these values + public const string CLIENT_ID = "1005421448355135520"; + public const string CLIENT_SECRET = "SmfsDIL-_SdC7FWvLF8hk1IsD_vML6C4"; + public const string REDIRECT_URI = "http://localhost:5000"; + public static string GuildID => MainService.DiscordWidgetAPI.id; + public static string[] TargetRoles = { "7094847781555405121" }; + + private static HttpListener _httpListener = new HttpListener(); + + private static GuildMember.Root CurrentUser = null; + public static bool IsServerBooster() + { + if (CurrentUser != null && CurrentUser.roles.Any(x => TargetRoles.Contains(x))) + { + return true; + } + + Console.WriteLine("Checking if you are a server booster..."); + + if (!_httpListener.Prefixes.Contains(REDIRECT_URI + "/")) + _httpListener.Prefixes.Add(REDIRECT_URI + "/"); + + if (!_httpListener.IsListening) + _httpListener.Start(); + + //First check if a previously stored auth token is saved. + start: if (MainService.CurrentConfig.OAuthToken != null) + { + CurrentUser = Discord.GetGuildMember(MainService.CurrentConfig.OAuthToken.access_token, GuildID).Result; + if (CurrentUser != null) + { + MainService.SaveConfig(); + if (CurrentUser.roles.Any(x => TargetRoles.Contains(x))) + { + Console.WriteLine("You are a server booster!"); + return true; + } + else + { + Console.WriteLine("It does not look like you're a server booster. Looks like you'll have to get a key through Linkvertise"); + return false; + } + + } + else + { + //Expired Auth Token + MainService.CurrentConfig.OAuthToken = null; + goto start; + } + } + else //No Auth token at all (OAuthToken == null) + { + //Start local server + string url = $"https://discord.com/api/oauth2/authorize?client_id={CLIENT_ID}&redirect_uri={REDIRECT_URI}&response_type=code&scope=guilds.members.read"; + Process webProcess = new Process(); + webProcess.StartInfo = new ProcessStartInfo() { UseShellExecute = true, FileName = url }; + webProcess.Start(); + + //Listen to server until OAuth is filled + while (MainService.CurrentConfig.OAuthToken == null) + { + HttpListenerContext context = _httpListener.GetContext(); // get a context + if (!string.IsNullOrEmpty(context.Request.Url.Query)) + { + NameValueCollection queryDictionary = HttpUtility.ParseQueryString(context.Request.Url.Query); + if (queryDictionary["code"] != null) + { + string DiscordCode = queryDictionary["code"]; + byte[] _responseArray = Encoding.UTF8.GetBytes($"You may close this tab now"); // get the bytes to response + context.Response.OutputStream.Write(_responseArray, 0, _responseArray.Length); // write bytes to the output stream + context.Response.KeepAlive = false; // set the KeepAlive bool to false + context.Response.Close(); // close the connection + //Console.Write("Received Discord Code: " + DiscordCode); + Console.WriteLine("Fetching access_token from Discord Code"); + MainService.CurrentConfig.OAuthToken = Discord.GetToken(DiscordCode).Result; + } + + } + } + goto start; + } + } + } + + internal class Discord + { + /// + /// Uses https://discord.com/api/oauth2/token endpoint and converts the code received from the browser to a bearer token + /// + /// + /// + /// Error from Discord API + public static async Task GetToken(string code) + { + HttpClient client = new(); + + var data = new[] + { + new KeyValuePair("client_id", DiscordRoleAuth.CLIENT_ID), + new KeyValuePair("client_secret", DiscordRoleAuth.CLIENT_SECRET), + new KeyValuePair("code", code), + new KeyValuePair("redirect_uri", DiscordRoleAuth.REDIRECT_URI), + new KeyValuePair("grant_type", "authorization_code"), + }; + var resp = await client.PostAsync("https://discord.com/api/oauth2/token", new FormUrlEncodedContent(data)); + string stringResp = await resp.Content.ReadAsStringAsync(); + if (resp.IsSuccessStatusCode) + return JsonSerializer.Deserialize(stringResp); + else + return null; + } + + + public static async Task GetGuildMember(string access_Token, string GuildID) + { + HttpClient client = new(); + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", access_Token); + string url = $"https://discord.com/api/users/@me/guilds/{GuildID}/member"; + var resp = await client.GetAsync(url); + string stringResp = await resp.Content.ReadAsStringAsync(); + if (resp.IsSuccessStatusCode) + { + return JsonSerializer.Deserialize(stringResp); + } + else + { + return null; + } + } + } +} diff --git a/Services/FortniteAPI.cs b/Services/FortniteAPI.cs new file mode 100644 index 0000000..3959b57 --- /dev/null +++ b/Services/FortniteAPI.cs @@ -0,0 +1,172 @@ +using CUE4Parse.Encryption.Aes; + +namespace ProSwapperLobby.Services +{ + public static class FortniteAPI + { + public static HttpClient http = new HttpClient(); + public const string FortniteAPIcomBaseURL = "https://fortnite-api.com/v2"; + public const string FortniteCentralBaseURL = "https://fortnitecentral.gmatrixgames.ga/api/v1"; + + private static FAesKey _aesKey = null; + private static string Version = null; + + public static FAesKey GetCurrentAESKey() + { + if (_aesKey == null) + { + try + { + string aesKey = FortniteAPIcom.AESResponse.GetData().data.mainKey; + if (aesKey != null && aesKey.Length > 0) + return new FAesKey(aesKey); + else + { + throw new Exception("Fortnite-api.com's AES Key was invalid"); + } + } + catch { } + + try + { + string aesKey = FortniteCentral.Rootobject.GetData().mainKey; + if (aesKey != null && aesKey.Length > 0) + return new FAesKey(aesKey); + } + catch { } + + + //This AES Key will not work but we dont want the user to have any errors + return new FAesKey(new string('0', 64)); + } + else + { + return _aesKey; + } + } + + public static string GetCurrentFortniteVersion() + { + if (Version == null) + { + try + { + string build = FortniteAPIcom.AESResponse.GetData().data.build; + if (build != null && build.Length > 0) + return build; + else + { + throw new Exception("Fortnite-api.com's Fortnite Version was invalid"); + } + } + catch { } + + try + { + string build = FortniteCentral.Rootobject.GetData().version; + if (build != null && build.Length > 0) + return build; + } + catch { } + + + //This AES Key will not work but we dont want the user to have any errors + return "Unknown Verson"; + } + else + { + return Version; + } + } + + } + + namespace FortniteAPIcom + { + + public class AESResponse + { + private static AESResponse.Root _data { get; set; } = null; + + public static AESResponse.Root GetData() + { + if (_data == null) + _data = MessagePack.MsgPacklz4($"{FortniteAPI.FortniteAPIcomBaseURL}/aes?responseFormat=msgpack_lz4&responseOptions=ignore_null"); + + return _data; + } + + public class Root + { + public int status { get; set; } + public Data data { get; set; } + } + + public class Data + { + public string build { get; set; } + public string mainKey { get; set; } + public Dynamickey[] dynamicKeys { get; set; } + public DateTime updated { get; set; } + } + + public class Dynamickey + { + public string pakFilename { get; set; } + public string pakGuid { get; set; } + public string key { get; set; } + } + } + } + + namespace FortniteCentral + { + + public class Rootobject + { + private static Rootobject _data { get; set; } = null; + + public static Rootobject GetData() + { + if (_data == null) + _data = FortniteAPI.http.GetFromJsonAsync($"{FortniteAPI.FortniteCentralBaseURL}/aes").Result; + + return _data; + } + + + public string version { get; set; } + public string mainKey { get; set; } + public Dynamickey[] dynamicKeys { get; set; } + public Unloaded[] unloaded { get; set; } + } + + public class Dynamickey + { + public string name { get; set; } + public string key { get; set; } + public string guid { get; set; } + public string keychain { get; set; } + public int fileCount { get; set; } + public bool hasHighResTextures { get; set; } + public Size size { get; set; } + } + + public class Size + { + public int raw { get; set; } + public string formatted { get; set; } + } + + public class Unloaded + { + public string name { get; set; } + public string guid { get; set; } + public int fileCount { get; set; } + public bool hasHighResTextures { get; set; } + public Size size { get; set; } + } + + } + +} diff --git a/Services/KeyService.cs b/Services/KeyService.cs new file mode 100644 index 0000000..b773960 --- /dev/null +++ b/Services/KeyService.cs @@ -0,0 +1,64 @@ +using System.Net; +using System.Security.Cryptography; +using System.Text; +using System.Diagnostics; +namespace ProSwapperLobby.Services +{ + public static class KeyService + { + public static string GetIPHash() => ComputeSHA256Hash(new WebClient().DownloadString("http://ip-api.com/line/?fields=8192").Replace("\n", "")); + + + public static string ComputeSHA256Hash(string text) => BitConverter.ToString(new SHA256Managed().ComputeHash(Encoding.UTF8.GetBytes(text))).Replace("-", ""); + + public static string CreateKey() => Base64Encode(GetIPHash() + DateTimeOffset.Now.ToUnixTimeSeconds().ToString()); + + public static string Base64Encode(string plainText) => Convert.ToBase64String(Encoding.UTF8.GetBytes(plainText)); + + public static string Base64Decode(string base64EncodedData) => Encoding.UTF8.GetString(Convert.FromBase64String(base64EncodedData)); + public static void OpenKeyUrl(string url) + { + Process process = new Process(); + process.StartInfo.UseShellExecute = true; + process.StartInfo.FileName = Base64Decode("aHR0cHM6Ly9saW5rLXRvLm5ldC84NjczNy81MzUuOTgzMDU5NTAyNDYxMy9keW5hbWljLz9yPQ==") + Base64Encode(url); + process.Start(); + } + + public static bool IsValidKey(string key) + { + if (string.IsNullOrEmpty(key)) + { + return false; + } + + //594e519ae499312b29433b7dd8a97ff068defcba9755b6d5d00e84c524d67b06 1659768999 + try + { + key = Base64Decode(key); + } + catch + { + return false; + } + + + long KeyExpireTime = long.Parse(key.Substring(64, key.Length - 64)) + MainService.ProSwapperAPI.KeyLifetime; + + long timeNow = DateTimeOffset.Now.ToUnixTimeSeconds(); + + /* + * OriginalKey = 1659768999 + * TimeNow = 1659768899 + * KeyExpireTime = OriginalKey + KeyLifeTime + * + * IF KeyExpireTime > TimeNow: + * //Key has not expired + * ELSE: + * //Key has expired + */ + + return KeyExpireTime > timeNow; + + } + } +} diff --git a/Services/MainService.cs b/Services/MainService.cs index d504979..80f00cb 100644 --- a/Services/MainService.cs +++ b/Services/MainService.cs @@ -12,8 +12,9 @@ public class MainService { public static readonly HttpClient client = new HttpClient(); public static string version = Assembly.GetEntryAssembly().GetName().Version.ToString().Substring(0, 5); - private const string FortniteAPIURL = "https://fortnite-api.com/v2"; + public static DiscordWidgetAPI.Root DiscordWidgetAPI { get; set; } + public static Data.API.Rootobject ProSwapperAPI { get; set; } #region FortniteItemAPIInstances @@ -29,7 +30,7 @@ public SkinObj.Root skinObj get { if (_skinObj == null) - _skinObj = MsgPacklz4($"{FortniteAPIURL}/cosmetics/br/search/all?backendType=AthenaCharacter&responseOptions=ignore_null&responseFormat=msgpack_lz4"); + _skinObj = MessagePack.MsgPacklz4($"{FortniteAPI.FortniteAPIcomBaseURL}/cosmetics/br/search/all?backendType=AthenaCharacter&responseOptions=ignore_null&responseFormat=msgpack_lz4"); return _skinObj; } } @@ -39,7 +40,7 @@ public SkinObj.Root backblingObj get { if (_backblingObj == null) - _backblingObj = MsgPacklz4($"{FortniteAPIURL}/cosmetics/br/search/all?backendType=AthenaBackpack&responseOptions=ignore_null&responseFormat=msgpack_lz4"); + _backblingObj = MessagePack.MsgPacklz4($"{FortniteAPI.FortniteAPIcomBaseURL}/cosmetics/br/search/all?backendType=AthenaBackpack&responseOptions=ignore_null&responseFormat=msgpack_lz4"); return _backblingObj; } } @@ -48,7 +49,7 @@ public SkinObj.Root emotesObj get { if (_emotesObj == null) - _emotesObj = MsgPacklz4($"{FortniteAPIURL}/cosmetics/br/search/all?backendType=AthenaDance&responseOptions=ignore_null&responseFormat=msgpack_lz4"); + _emotesObj = MessagePack.MsgPacklz4($"{FortniteAPI.FortniteAPIcomBaseURL}/cosmetics/br/search/all?backendType=AthenaDance&responseOptions=ignore_null&responseFormat=msgpack_lz4"); return _emotesObj; } } @@ -58,7 +59,7 @@ public SkinObj.Root pickaxeObj get { if (_pickaxeObj == null) - _pickaxeObj = MsgPacklz4($"{FortniteAPIURL}/cosmetics/br/search/all?backendType=AthenaPickaxe&responseOptions=ignore_null&responseFormat=msgpack_lz4"); + _pickaxeObj = MessagePack.MsgPacklz4($"{FortniteAPI.FortniteAPIcomBaseURL}/cosmetics/br/search/all?backendType=AthenaPickaxe&responseOptions=ignore_null&responseFormat=msgpack_lz4"); return _pickaxeObj; } } @@ -68,7 +69,7 @@ public SkinObj.Root musicObj get { if (_musicObj == null) - _musicObj = MsgPacklz4($"{FortniteAPIURL}/cosmetics/br/search/all?backendType=AthenaMusicPack&responseOptions=ignore_null&responseFormat=msgpack_lz4"); + _musicObj = MessagePack.MsgPacklz4($"{FortniteAPI.FortniteAPIcomBaseURL}/cosmetics/br/search/all?backendType=AthenaMusicPack&responseOptions=ignore_null&responseFormat=msgpack_lz4"); return _musicObj; } } @@ -77,7 +78,7 @@ public SkinObj.Root gliderObj get { if (_gliderObj == null) - _gliderObj = MsgPacklz4($"{FortniteAPIURL}/cosmetics/br/search/all?backendType=AthenaGlider&responseOptions=ignore_null&responseFormat=msgpack_lz4"); + _gliderObj = MessagePack.MsgPacklz4($"{FortniteAPI.FortniteAPIcomBaseURL}/cosmetics/br/search/all?backendType=AthenaGlider&responseOptions=ignore_null&responseFormat=msgpack_lz4"); return _gliderObj; } } @@ -93,21 +94,7 @@ public AllSkinsJson.Root AllSkins() #endregion - /// - /// Input a url which responds with msgpack compressed in lz4, responds with json object which is 'T' - /// - /// - /// - /// - public static T MsgPacklz4(string url) - { - Stream responseBody = client.GetStreamAsync(url).Result; - var lz4Options = MessagePackSerializerOptions.Standard.WithCompression(MessagePackCompression.Lz4BlockArray); - var AllCosmeticsLz4 = MessagePackSerializer.Deserialize(responseBody, lz4Options); - string json = MessagePackSerializer.SerializeToJson(AllCosmeticsLz4, lz4Options); - return JsonConvert.DeserializeObject(json); - } /// @@ -134,38 +121,15 @@ public SwapLogs(SkinObj.Datum _SwapsFrom, SkinObj.Datum _SwapsTo) } } - public class AESResponse - { - public class Root - { - public int status { get; set; } - public Data data { get; set; } - } - - public class Data - { - public string build { get; set; } - public string mainKey { get; set; } - public Dynamickey[] dynamicKeys { get; set; } - public DateTime updated { get; set; } - } - - public class Dynamickey - { - public string pakFilename { get; set; } - public string pakGuid { get; set; } - public string key { get; set; } - } - } - #region ConfigHandler - private static string ConfigPath => ProSwapperFolder + @".Config\" + version + "_config.json"; + private static string ConfigPath => ProSwapperFolder + @"ProSwapperLobby\" + version + "_config.json"; public static ConfigObj CurrentConfig; public static void InitConfig() { + Directory.CreateDirectory(ProSwapperFolder + @"ProSwapperLobby\"); if (!File.Exists(ConfigPath)) File.WriteAllText(ConfigPath, JsonConvert.SerializeObject(new ConfigObj()), System.Text.Encoding.Unicode); CurrentConfig = JsonConvert.DeserializeObject(File.ReadAllText(ConfigPath)); @@ -173,18 +137,15 @@ public static void InitConfig() public static void SaveConfig() => File.WriteAllText(ConfigPath, JsonConvert.SerializeObject(CurrentConfig), System.Text.Encoding.Unicode); - private static FAesKey _aesKey { get; set; } = null; private static string _Paks { get; set; } = null; - private static string _fnVer { get; set; } = null; - private static AESResponse.Root aesResponse { get; set; } = null; - - - public class ConfigObj { public List swaplogs { get; set; } = new List(); + public string Key { get; set; } = ""; + public Services.TokenResponse.Root OAuthToken { get; set; } = null;//Uses Discord OAuth2 + public bool AskIfServerBooster { get; set; } = true; public string Paks { get @@ -203,21 +164,7 @@ public string Paks } } - public FAesKey? aesKey - { - get - { - if (aesResponse == null) - aesResponse = MsgPacklz4($"{FortniteAPIURL}/aes?responseFormat=msgpack_lz4&responseOptions=ignore_null"); - - if (aesResponse.data.mainKey != null && _aesKey == null) - { - _aesKey = new FAesKey(aesResponse.data.mainKey); - } - - return _aesKey; - } - } + public FAesKey? aesKey => FortniteAPI.GetCurrentAESKey(); public string CurrentInstalledFortniteVersion { @@ -228,20 +175,10 @@ public string CurrentInstalledFortniteVersion return SwapperLogic.EpicGamesLauncher.GetCurrentInstalledFortniteVersion(); } catch { return null; } - } } - public string CurrentLiveFortniteVersion - { - get - { - if (aesResponse == null) - aesResponse = MsgPacklz4($"{FortniteAPIURL}/aes?responseFormat=msgpack_lz4&responseOptions=ignore_null"); - - return aesResponse.data.build; - } - } + public string CurrentLiveFortniteVersion => FortniteAPI.GetCurrentFortniteVersion(); } #endregion diff --git a/Services/MessagePack.cs b/Services/MessagePack.cs new file mode 100644 index 0000000..f86899a --- /dev/null +++ b/Services/MessagePack.cs @@ -0,0 +1,25 @@ +using MessagePack; +using Newtonsoft.Json; + +namespace ProSwapperLobby.Services +{ + public static class MessagePack + { + public static readonly HttpClient client = new HttpClient(); + /// + /// Input a url which responds with msgpack compressed in lz4, responds with json object which is 'T' + /// + /// + /// + /// + public static T MsgPacklz4(string url) + { + Stream responseBody = client.GetStreamAsync(url).Result; + var lz4Options = MessagePackSerializerOptions.Standard.WithCompression(MessagePackCompression.Lz4BlockArray); + var AllCosmeticsLz4 = MessagePackSerializer.Deserialize(responseBody, lz4Options); + string json = MessagePackSerializer.SerializeToJson(AllCosmeticsLz4, lz4Options); + return JsonConvert.DeserializeObject(json); + + } + } +} diff --git a/Shared/NavMenu.razor b/Shared/NavMenu.razor index 170f184..94174e9 100644 --- a/Shared/NavMenu.razor +++ b/Shared/NavMenu.razor @@ -46,21 +46,27 @@ beach_access Gliders
    - *@ + + @* + *@ diff --git a/Shared/SurveyPrompt.razor b/Shared/SurveyPrompt.razor deleted file mode 100644 index e3e6429..0000000 --- a/Shared/SurveyPrompt.razor +++ /dev/null @@ -1,16 +0,0 @@ -
    - - @Title - - - Please take our - brief survey - - and tell us what you think. -
    - -@code { - // Demonstrates how a parent component can supply parameters - [Parameter] - public string? Title { get; set; } -} diff --git a/SwapperLogic/SwapLogic.cs b/SwapperLogic/SwapLogic.cs index 16390a1..16bada9 100644 --- a/SwapperLogic/SwapLogic.cs +++ b/SwapperLogic/SwapLogic.cs @@ -21,11 +21,11 @@ public static class SwapLogic public static DefaultFileProvider GetProvider(string folderPath, string[] LoadSpecific = null) { if (LoadSpecific == null) - LoadSpecific = new[] { "."}; + LoadSpecific = new[] { "." }; var Provider = new DefaultFileProvider(folderPath, SearchOption.TopDirectoryOnly, false, new VersionContainer(EGame.GAME_UE5_1)); Provider.Initialize(); - + //Provider.LoadMappings(); Don't need mappings for asset reg foreach (var vfs in Provider.UnloadedVfs.Where(x => LoadSpecific.Any(x.Name.Contains))) { Provider.SubmitKey(vfs.EncryptionKeyGuid, MainService.CurrentConfig.aesKey); @@ -66,7 +66,7 @@ public static bool LobbySwap(SkinObj.Datum SwapsFrom, SkinObj.Datum SwapsTo, boo { try { - + string LobbyPaksPath = Path.Combine(Services.MainService.CurrentConfig.Paks, ProSwapperLobby); @@ -109,6 +109,8 @@ public static bool LobbySwap(SkinObj.Datum SwapsFrom, SkinObj.Datum SwapsTo, boo SearchCID_s = SwapsFrom.id + "." + SwapsFrom.id; + byte[] a = provider.SaveAsset("FortniteGame/AssetRegistry.bin"); + if (provider.TrySaveAsset("FortniteGame/AssetRegistry.bin", out byte[] _)) { provider.Dispose();