├── .gitattributes
├── .gitignore
├── App.xaml
├── App.xaml.cs
├── Assets
├── ACTUALL ICON.ico
├── Banner.png
├── PFP.png
├── ShieldExclamationMark.png
├── SplashScreen.scale-200.png
├── Square150x150Logo.scale-200.png
├── Square44x44Logo.scale-200.png
├── Square44x44Logo.targetsize-24_altform-unplated.png
├── StoreLogo.png
├── Wide310x150Logo.scale-200.png
├── backend.png
├── charity-removebg-preview.png
├── discord.png
├── playerstats.png
├── tiltedlogo.png
└── warning.png
├── Config.cs
├── Core
├── API.cs
├── DiscordRPC
│ └── ExitRPC.cs
├── Launcher
│ ├── AsyncStreamReader.cs
│ ├── CheckSuspendedProcess.cs
│ ├── CrashHandler.cs
│ └── Launcher.cs
├── Loops
│ └── AccountCheck.cs
├── Mods
│ ├── Anticheat.cs
│ ├── DownloadFile.cs
│ └── WhitelistedProcesses.cs
├── MongDB
│ └── MongoDB.cs
├── Settings.cs
├── Updates
│ └── CheckForUpdates.cs
└── def
│ └── Definitions.cs
├── Dialogs
├── DownloadDialog.xaml
└── DownloadDialog.xaml.cs
├── ExitLauncher.csproj
├── ExitLauncher.sln
├── Globals.cs
├── Helpers
├── PathHelper.cs
└── StorageSizesConverter.cs
├── Interop
└── MessageBox.cs
├── MainWindow.xaml
├── MainWindow.xaml.cs
├── Package.appxmanifest
├── Pages
├── DownloadsPage.xaml
├── DownloadsPage.xaml.cs
├── HomePage.xaml
├── HomePage.xaml.cs
├── ItemShopPage.xaml
├── ItemShopPage.xaml.cs
├── LoginPage.xaml
├── LoginPage.xaml.cs
├── MainShellPage.xaml
├── MainShellPage.xaml.cs
├── PlayPage.xaml
├── PlayPage.xaml.cs
├── ServerStatusPage.xaml
├── ServerStatusPage.xaml.cs
├── SettingsPage.xaml
└── SettingsPage.xaml.cs
├── Properties
└── launchSettings.json
├── README.md
├── Services
├── DialogService.cs
├── NavigationService.cs
└── ThemeService.cs
└── app.manifest
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.rsuser
8 | *.suo
9 | *.user
10 | *.userosscache
11 | *.sln.docstates
12 |
13 | # User-specific files (MonoDevelop/Xamarin Studio)
14 | *.userprefs
15 |
16 | # Mono auto generated files
17 | mono_crash.*
18 |
19 | # Build results
20 | [Dd]ebug/
21 | [Dd]ebugPublic/
22 | [Rr]elease/
23 | [Rr]eleases/
24 | x64/
25 | x86/
26 | [Ww][Ii][Nn]32/
27 | [Aa][Rr][Mm]/
28 | [Aa][Rr][Mm]64/
29 | bld/
30 | [Bb]in/
31 | [Oo]bj/
32 | [Oo]ut/
33 | [Ll]og/
34 | [Ll]ogs/
35 |
36 | # Visual Studio 2015/2017 cache/options directory
37 | .vs/
38 | # Uncomment if you have tasks that create the project's static files in wwwroot
39 | #wwwroot/
40 |
41 | # Visual Studio 2017 auto generated files
42 | Generated\ Files/
43 |
44 | # MSTest test Results
45 | [Tt]est[Rr]esult*/
46 | [Bb]uild[Ll]og.*
47 |
48 | # NUnit
49 | *.VisualState.xml
50 | TestResult.xml
51 | nunit-*.xml
52 |
53 | # Build Results of an ATL Project
54 | [Dd]ebugPS/
55 | [Rr]eleasePS/
56 | dlldata.c
57 |
58 | # Benchmark Results
59 | BenchmarkDotNet.Artifacts/
60 |
61 | # .NET Core
62 | project.lock.json
63 | project.fragment.lock.json
64 | artifacts/
65 |
66 | # ASP.NET Scaffolding
67 | ScaffoldingReadMe.txt
68 |
69 | # StyleCop
70 | StyleCopReport.xml
71 |
72 | # Files built by Visual Studio
73 | *_i.c
74 | *_p.c
75 | *_h.h
76 | *.ilk
77 | *.meta
78 | *.obj
79 | *.iobj
80 | *.pch
81 | *.pdb
82 | *.ipdb
83 | *.pgc
84 | *.pgd
85 | *.rsp
86 | *.sbr
87 | *.tlb
88 | *.tli
89 | *.tlh
90 | *.tmp
91 | *.tmp_proj
92 | *_wpftmp.csproj
93 | *.log
94 | *.vspscc
95 | *.vssscc
96 | .builds
97 | *.pidb
98 | *.svclog
99 | *.scc
100 |
101 | # Chutzpah Test files
102 | _Chutzpah*
103 |
104 | # Visual C++ cache files
105 | ipch/
106 | *.aps
107 | *.ncb
108 | *.opendb
109 | *.opensdf
110 | *.sdf
111 | *.cachefile
112 | *.VC.db
113 | *.VC.VC.opendb
114 |
115 | # Visual Studio profiler
116 | *.psess
117 | *.vsp
118 | *.vspx
119 | *.sap
120 |
121 | # Visual Studio Trace Files
122 | *.e2e
123 |
124 | # TFS 2012 Local Workspace
125 | $tf/
126 |
127 | # Guidance Automation Toolkit
128 | *.gpState
129 |
130 | # ReSharper is a .NET coding add-in
131 | _ReSharper*/
132 | *.[Rr]e[Ss]harper
133 | *.DotSettings.user
134 |
135 | # TeamCity is a build add-in
136 | _TeamCity*
137 |
138 | # DotCover is a Code Coverage Tool
139 | *.dotCover
140 |
141 | # AxoCover is a Code Coverage Tool
142 | .axoCover/*
143 | !.axoCover/settings.json
144 |
145 | # Coverlet is a free, cross platform Code Coverage Tool
146 | coverage*.json
147 | coverage*.xml
148 | coverage*.info
149 |
150 | # Visual Studio code coverage results
151 | *.coverage
152 | *.coveragexml
153 |
154 | # NCrunch
155 | _NCrunch_*
156 | .*crunch*.local.xml
157 | nCrunchTemp_*
158 |
159 | # MightyMoose
160 | *.mm.*
161 | AutoTest.Net/
162 |
163 | # Web workbench (sass)
164 | .sass-cache/
165 |
166 | # Installshield output folder
167 | [Ee]xpress/
168 |
169 | # DocProject is a documentation generator add-in
170 | DocProject/buildhelp/
171 | DocProject/Help/*.HxT
172 | DocProject/Help/*.HxC
173 | DocProject/Help/*.hhc
174 | DocProject/Help/*.hhk
175 | DocProject/Help/*.hhp
176 | DocProject/Help/Html2
177 | DocProject/Help/html
178 |
179 | # Click-Once directory
180 | publish/
181 |
182 | # Publish Web Output
183 | *.[Pp]ublish.xml
184 | *.azurePubxml
185 | # Note: Comment the next line if you want to checkin your web deploy settings,
186 | # but database connection strings (with potential passwords) will be unencrypted
187 | *.pubxml
188 | *.publishproj
189 |
190 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
191 | # checkin your Azure Web App publish settings, but sensitive information contained
192 | # in these scripts will be unencrypted
193 | PublishScripts/
194 |
195 | # NuGet Packages
196 | *.nupkg
197 | # NuGet Symbol Packages
198 | *.snupkg
199 | # The packages folder can be ignored because of Package Restore
200 | **/[Pp]ackages/*
201 | # except build/, which is used as an MSBuild target.
202 | !**/[Pp]ackages/build/
203 | # Uncomment if necessary however generally it will be regenerated when needed
204 | #!**/[Pp]ackages/repositories.config
205 | # NuGet v3's project.json files produces more ignorable files
206 | *.nuget.props
207 | *.nuget.targets
208 |
209 | # Microsoft Azure Build Output
210 | csx/
211 | *.build.csdef
212 |
213 | # Microsoft Azure Emulator
214 | ecf/
215 | rcf/
216 |
217 | # Windows Store app package directories and files
218 | AppPackages/
219 | BundleArtifacts/
220 | Package.StoreAssociation.xml
221 | _pkginfo.txt
222 | *.appx
223 | *.appxbundle
224 | *.appxupload
225 |
226 | # Visual Studio cache files
227 | # files ending in .cache can be ignored
228 | *.[Cc]ache
229 | # but keep track of directories ending in .cache
230 | !?*.[Cc]ache/
231 |
232 | # Others
233 | ClientBin/
234 | ~$*
235 | *~
236 | *.dbmdl
237 | *.dbproj.schemaview
238 | *.jfm
239 | *.pfx
240 | *.publishsettings
241 | orleans.codegen.cs
242 |
243 | # Including strong name files can present a security risk
244 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
245 | #*.snk
246 |
247 | # Since there are multiple workflows, uncomment next line to ignore bower_components
248 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
249 | #bower_components/
250 |
251 | # RIA/Silverlight projects
252 | Generated_Code/
253 |
254 | # Backup & report files from converting an old project file
255 | # to a newer Visual Studio version. Backup files are not needed,
256 | # because we have git ;-)
257 | _UpgradeReport_Files/
258 | Backup*/
259 | UpgradeLog*.XML
260 | UpgradeLog*.htm
261 | ServiceFabricBackup/
262 | *.rptproj.bak
263 |
264 | # SQL Server files
265 | *.mdf
266 | *.ldf
267 | *.ndf
268 |
269 | # Business Intelligence projects
270 | *.rdl.data
271 | *.bim.layout
272 | *.bim_*.settings
273 | *.rptproj.rsuser
274 | *- [Bb]ackup.rdl
275 | *- [Bb]ackup ([0-9]).rdl
276 | *- [Bb]ackup ([0-9][0-9]).rdl
277 |
278 | # Microsoft Fakes
279 | FakesAssemblies/
280 |
281 | # GhostDoc plugin setting file
282 | *.GhostDoc.xml
283 |
284 | # Node.js Tools for Visual Studio
285 | .ntvs_analysis.dat
286 | node_modules/
287 |
288 | # Visual Studio 6 build log
289 | *.plg
290 |
291 | # Visual Studio 6 workspace options file
292 | *.opt
293 |
294 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
295 | *.vbw
296 |
297 | # Visual Studio LightSwitch build output
298 | **/*.HTMLClient/GeneratedArtifacts
299 | **/*.DesktopClient/GeneratedArtifacts
300 | **/*.DesktopClient/ModelManifest.xml
301 | **/*.Server/GeneratedArtifacts
302 | **/*.Server/ModelManifest.xml
303 | _Pvt_Extensions
304 |
305 | # Paket dependency manager
306 | .paket/paket.exe
307 | paket-files/
308 |
309 | # FAKE - F# Make
310 | .fake/
311 |
312 | # CodeRush personal settings
313 | .cr/personal
314 |
315 | # Python Tools for Visual Studio (PTVS)
316 | __pycache__/
317 | *.pyc
318 |
319 | # Cake - Uncomment if you are using it
320 | # tools/**
321 | # !tools/packages.config
322 |
323 | # Tabs Studio
324 | *.tss
325 |
326 | # Telerik's JustMock configuration file
327 | *.jmconfig
328 |
329 | # BizTalk build output
330 | *.btp.cs
331 | *.btm.cs
332 | *.odx.cs
333 | *.xsd.cs
334 |
335 | # OpenCover UI analysis results
336 | OpenCover/
337 |
338 | # Azure Stream Analytics local run output
339 | ASALocalRun/
340 |
341 | # MSBuild Binary and Structured Log
342 | *.binlog
343 |
344 | # NVidia Nsight GPU debugger configuration file
345 | *.nvuser
346 |
347 | # MFractors (Xamarin productivity tool) working folder
348 | .mfractor/
349 |
350 | # Local History for Visual Studio
351 | .localhistory/
352 |
353 | # BeatPulse healthcheck temp database
354 | healthchecksdb
355 |
356 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
357 | MigrationBackup/
358 |
359 | # Ionide (cross platform F# VS Code tools) working folder
360 | .ionide/
361 |
362 | # Fody - auto-generated XML schema
363 | FodyWeavers.xsd
--------------------------------------------------------------------------------
/App.xaml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.UI.Xaml;
2 | using Microsoft.UI.Xaml.Controls;
3 | using Microsoft.UI.Xaml.Controls.Primitives;
4 | using Microsoft.UI.Xaml.Data;
5 | using Microsoft.UI.Xaml.Input;
6 | using Microsoft.UI.Xaml.Media;
7 | using Microsoft.UI.Xaml.Navigation;
8 | using Microsoft.UI.Xaml.Shapes;
9 | using FortniteLauncher.Core;
10 | using FortniteLauncher.Interop;
11 | using FortniteLauncher.Services;
12 | using System;
13 | using System.Collections.Generic;
14 | using System.IO;
15 | using System.Linq;
16 | using System.Runtime.InteropServices.WindowsRuntime;
17 | using System.Threading;
18 | using Windows.ApplicationModel;
19 | using Windows.ApplicationModel.Activation;
20 | using Windows.Foundation;
21 | using Windows.Foundation.Collections;
22 |
23 | // To learn more about WinUI, the WinUI project structure,
24 | // and more about our project templates, see: http://aka.ms/winui-project-info.
25 |
26 | namespace FortniteLauncher
27 | {
28 | ///
29 | /// Provides application-specific behavior to supplement the default Application class.
30 | ///
31 | public partial class App : Application
32 | {
33 | ///
34 | /// Initializes the singleton application object. This is the first line of authored code
35 | /// executed, and as such is the logical equivalent of main() or WinMain().
36 | ///
37 | public App()
38 | {
39 | this.InitializeComponent();
40 | ExitRPC.Start();
41 | bool createdNew;
42 | Mutex mutex = new Mutex(true, "ExitLauncher", out createdNew);
43 |
44 | if (createdNew)
45 | {
46 | mutex.ReleaseMutex();
47 | }
48 | else
49 | {
50 | MessageBox.Show("Exit Launcher is already running. Please close it before opening a new instance.", "Already Running");
51 | Environment.Exit(1);
52 | }
53 | }
54 |
55 | ///
56 | /// Invoked when the application is launched.
57 | ///
58 | /// Details about the launch request and process.
59 | protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
60 | {
61 | m_window = new MainWindow();
62 | m_window.Activate();
63 |
64 | Globals.m_window = m_window;
65 |
66 | Settings.LoadSettings();
67 |
68 | ThemeService.ChangeTheme(ElementTheme.Dark);//force the dark theme
69 | if (Globals.m_config.IsSoundEnabled)
70 | {
71 | ElementSoundPlayer.State = ElementSoundPlayerState.On;
72 | }
73 | }
74 |
75 | private Window m_window;
76 |
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/Assets/ACTUALL ICON.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExitFN/Exit-Launcher/ebb5da3f01f9a8b668cc72fc59542137677ded46/Assets/ACTUALL ICON.ico
--------------------------------------------------------------------------------
/Assets/Banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExitFN/Exit-Launcher/ebb5da3f01f9a8b668cc72fc59542137677ded46/Assets/Banner.png
--------------------------------------------------------------------------------
/Assets/PFP.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExitFN/Exit-Launcher/ebb5da3f01f9a8b668cc72fc59542137677ded46/Assets/PFP.png
--------------------------------------------------------------------------------
/Assets/ShieldExclamationMark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExitFN/Exit-Launcher/ebb5da3f01f9a8b668cc72fc59542137677ded46/Assets/ShieldExclamationMark.png
--------------------------------------------------------------------------------
/Assets/SplashScreen.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExitFN/Exit-Launcher/ebb5da3f01f9a8b668cc72fc59542137677ded46/Assets/SplashScreen.scale-200.png
--------------------------------------------------------------------------------
/Assets/Square150x150Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExitFN/Exit-Launcher/ebb5da3f01f9a8b668cc72fc59542137677ded46/Assets/Square150x150Logo.scale-200.png
--------------------------------------------------------------------------------
/Assets/Square44x44Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExitFN/Exit-Launcher/ebb5da3f01f9a8b668cc72fc59542137677ded46/Assets/Square44x44Logo.scale-200.png
--------------------------------------------------------------------------------
/Assets/Square44x44Logo.targetsize-24_altform-unplated.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExitFN/Exit-Launcher/ebb5da3f01f9a8b668cc72fc59542137677ded46/Assets/Square44x44Logo.targetsize-24_altform-unplated.png
--------------------------------------------------------------------------------
/Assets/StoreLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExitFN/Exit-Launcher/ebb5da3f01f9a8b668cc72fc59542137677ded46/Assets/StoreLogo.png
--------------------------------------------------------------------------------
/Assets/Wide310x150Logo.scale-200.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExitFN/Exit-Launcher/ebb5da3f01f9a8b668cc72fc59542137677ded46/Assets/Wide310x150Logo.scale-200.png
--------------------------------------------------------------------------------
/Assets/backend.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExitFN/Exit-Launcher/ebb5da3f01f9a8b668cc72fc59542137677ded46/Assets/backend.png
--------------------------------------------------------------------------------
/Assets/charity-removebg-preview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExitFN/Exit-Launcher/ebb5da3f01f9a8b668cc72fc59542137677ded46/Assets/charity-removebg-preview.png
--------------------------------------------------------------------------------
/Assets/discord.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExitFN/Exit-Launcher/ebb5da3f01f9a8b668cc72fc59542137677ded46/Assets/discord.png
--------------------------------------------------------------------------------
/Assets/playerstats.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExitFN/Exit-Launcher/ebb5da3f01f9a8b668cc72fc59542137677ded46/Assets/playerstats.png
--------------------------------------------------------------------------------
/Assets/tiltedlogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExitFN/Exit-Launcher/ebb5da3f01f9a8b668cc72fc59542137677ded46/Assets/tiltedlogo.png
--------------------------------------------------------------------------------
/Assets/warning.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ExitFN/Exit-Launcher/ebb5da3f01f9a8b668cc72fc59542137677ded46/Assets/warning.png
--------------------------------------------------------------------------------
/Config.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.UI.Xaml;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace FortniteLauncher
9 | {
10 | public class Config
11 | {
12 | public bool IsSoundEnabled;
13 |
14 | public string FortnitePath;
15 |
16 | public string Username { get; set; }
17 | public string Email { get; set; }
18 | public string Password { get; set; }
19 |
20 |
21 | ///defaults
22 | ///Dark Theme
23 | ///Sound Disabled
24 | ///EOR Enabled
25 | //////Close On launch Disabled
26 | ///
27 | ///Username, email and password are empty and will be set at runtime
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Core/DiscordRPC/ExitRPC.cs:
--------------------------------------------------------------------------------
1 | using Amazon.Runtime.Internal.Endpoints.StandardLibrary;
2 | using DiscordRPC;
3 | using MongoDB.Bson.Serialization.Serializers;
4 | using System;
5 | using System.Reflection.Emit;
6 | using System.Threading;
7 | using System.Threading.Tasks;
8 |
9 | public class ExitRPC
10 | {
11 | private static DiscordRpcClient client;
12 |
13 | public static async void Start()
14 | {
15 | if (client == null)
16 | {
17 | client = new DiscordRpcClient("put your discord bot id here so discord rpc works but this config is for my client so change it");
18 |
19 | client.Initialize();
20 | }
21 |
22 | if (client.IsInitialized)
23 | {
24 | if (Definitions.DiscordPRC == true)
25 | {
26 | if (Definitions.UserName == null)
27 | {
28 | while (Definitions.UserName == null)
29 | {
30 | await Task.Delay(1000);
31 | }
32 | UpdatePresence("Logged in as " + Definitions.UserName, "");
33 | }
34 | }
35 | }
36 |
37 | }
38 |
39 | public static void Stop()
40 | {
41 | if (client != null && client.IsInitialized)
42 | {
43 | client.ClearPresence();
44 | client.Deinitialize();
45 | }
46 | }
47 |
48 | public static void UpdatePresence(string state, string details)
49 | {
50 | if (client.IsInitialized)
51 | {
52 | client.SetPresence(new RichPresence()
53 | {
54 | State = state,
55 | Details = details,
56 | Timestamps = new Timestamps()
57 | {
58 | Start = DateTime.UtcNow
59 | },
60 | Assets = new Assets()
61 | {
62 | LargeImageKey = "exit",
63 | LargeImageText = "Exit",
64 | SmallImageKey = "battlepass",
65 | SmallImageText = "Tier 100"
66 | },
67 | Buttons = new Button[]
68 | {
69 | new Button() { Label = "Join Exit Discord", Url = "https://discord.gg/exitfn" },
70 | new Button() { Label = "Join Support Server", Url = "https://discord.gg/Wx9pHBW3Tm" }
71 | }
72 | });
73 | }
74 | }
75 |
76 | }
--------------------------------------------------------------------------------
/Core/Launcher/AsyncStreamReader.cs:
--------------------------------------------------------------------------------
1 | // CREDITS: https://github.com/Londiuh/FortniteLauncher/blob/master/FortniteLauncher/Utilities/AsyncStreamReader.cs
2 | using System;
3 | using System.IO;
4 |
5 | public partial class AsyncStreamReader
6 | {
7 | public event EventHandler DataReceived;
8 |
9 | public bool Active { get; private set; }
10 |
11 | public AsyncStreamReader(StreamReader reader)
12 | {
13 | _reader = reader;
14 | Active = false;
15 | }
16 |
17 | public void Start()
18 | {
19 | if (!Active)
20 | {
21 | Active = true;
22 | BeginReadAsync();
23 | }
24 | }
25 |
26 | public void Stop()
27 | {
28 | Active = false;
29 | }
30 |
31 | protected void BeginReadAsync()
32 | {
33 | if (Active) _reader.BaseStream.BeginRead(_buffer, 0, _buffer.Length, new AsyncCallback(ReadCallback), null);
34 | }
35 |
36 | private void ReadCallback(IAsyncResult asyncResult)
37 | {
38 | if (_reader == null) return;
39 |
40 | int num = _reader.BaseStream.EndRead(asyncResult);
41 | string data = null;
42 |
43 | if (num > 0)
44 | data = _reader.CurrentEncoding.GetString(_buffer, 0, num);
45 | else
46 | Active = false;
47 |
48 | DataReceived?.Invoke(this, data);
49 |
50 | BeginReadAsync();
51 | }
52 |
53 | protected readonly byte[] _buffer = new byte[4096];
54 |
55 | private StreamReader _reader;
56 |
57 | public delegate void EventHandler(object sender, string data);
58 | }
59 |
--------------------------------------------------------------------------------
/Core/Launcher/CheckSuspendedProcess.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace FortniteLauncher.CheckSuspendedProcess
5 | {
6 | public static class NativeMethodsProc
7 | {
8 | [DllImport("ntdll.dll")]
9 | public static extern int NtQueryInformationProcess(IntPtr processHandle, int processInformationClass, out int processInformation, int processInformationLength, IntPtr returnLength);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Core/Launcher/CrashHandler.cs:
--------------------------------------------------------------------------------
1 | using FortniteLauncher;
2 | using FortniteLauncher.Interop;
3 | using FortniteLauncher.Services;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Diagnostics;
7 | using System.IO;
8 | using System.IO.Compression;
9 | using System.Linq;
10 | using System.Text;
11 | using System.Threading;
12 | using System.Threading.Tasks;
13 |
14 | class CrashHandler
15 | {
16 | public static async Task Start()
17 | {
18 | string processName = "CrashReportClient";
19 | bool isProcessRunning;
20 | int crashes = 5;
21 | while (true)
22 | {
23 | isProcessRunning = IsProcessRunning(processName);
24 |
25 | if (isProcessRunning)
26 | {
27 | Fortnite.KillFnProc();
28 | bool repairfiles = await DialogService.YesOrNoDialog("Fortnite has crashed would you like to repair the files? Note: All in game settings will be reset!", "Fatal Error");
29 | crashes++;
30 | if (crashes < 5)
31 | {
32 | bool sendlogs = await DialogService.YesOrNoDialog("Fortnite has crashed to many times please create a ticket in the Discord server and provide them with the zip file.", "Fatal Error");
33 | if (sendlogs)
34 | {
35 | string localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
36 | Fortnite.KillFnProc();
37 |
38 | // Define the source directory to be zipped
39 | string sourceDirectory = localAppData + "\\FortniteGame";
40 |
41 | if (Directory.Exists(sourceDirectory))
42 | {
43 | // Define the path to the log file to be included in the zip
44 | string logFilePath = sourceDirectory + "\\Saved\\Logs\\FortniteGame.log";
45 |
46 | if (File.Exists(logFilePath))
47 | {
48 | string CurrentDirectory = Directory.GetCurrentDirectory();
49 | if (!Directory.Exists(CurrentDirectory + "\\Support\\Logs"))
50 | {
51 | Directory.CreateDirectory(CurrentDirectory + "\\Support\\Logs");
52 | }
53 | string zipFilePath = CurrentDirectory + "\\Support\\Logs\\";
54 | Process.Start(zipFilePath);
55 | ZipFile.CreateFromDirectory(sourceDirectory, zipFilePath);
56 | }
57 | }
58 | }
59 | return;
60 | }
61 | if (repairfiles)
62 | {
63 | try
64 | {
65 | string localAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
66 | Fortnite.KillFnProc();
67 | if (Directory.Exists(localAppData + "\\FortniteGame"))
68 | {
69 | Directory.Delete(localAppData + "\\FortniteGame", true);
70 | }
71 | if (Directory.Exists(Globals.m_config.FortnitePath + "\\EasyAntiCheat"))
72 | {
73 | Directory.Delete(Globals.m_config.FortnitePath + "\\EasyAntiCheat", true);
74 | }
75 | if (File.Exists(Globals.m_config.FortnitePath + "\\ExitClient-Win64-Shipping.exe"))
76 | {
77 | File.Delete(Globals.m_config.FortnitePath + "\\ExitClient-Win64-Shipping.exe");
78 | }
79 | if (File.Exists(Globals.m_config.FortnitePath + "\\Engine\\Binaries\\ThirdParty\\NVIDIA\\NVaftermath\\Win64\\GFSDK_Aftermath_Lib.x64.dll"))
80 | {
81 | File.Delete(Globals.m_config.FortnitePath + "\\Engine\\Binaries\\ThirdParty\\NVIDIA\\NVaftermath\\Win64\\GFSDK_Aftermath_Lib.x64.dll");
82 | }
83 | await Task.Delay(5000);
84 | DialogService.ShowSimpleDialog("Fortnite files have been repaired successfully.", "Success");
85 | } catch { }
86 |
87 | }
88 | break;
89 | }
90 | await Task.Delay(1000);
91 | }
92 | }
93 |
94 |
95 | static bool IsProcessRunning(string processName)
96 | {
97 | Process[] processes = Process.GetProcessesByName(processName);
98 |
99 | return processes.Length > 0;
100 | }
101 | }
--------------------------------------------------------------------------------
/Core/Launcher/Launcher.cs:
--------------------------------------------------------------------------------
1 | using ABI.Windows.ApplicationModel.Activation;
2 | using Amazon.Auth.AccessControlPolicy;
3 | using CommunityToolkit.Labs.WinUI;
4 | using Microsoft.UI.Xaml;
5 | using Microsoft.UI.Xaml.Controls;
6 | using Microsoft.UI.Xaml.Shapes; // Make sure this is fully qualified.
7 | using MongoDB.Driver.Core.Misc;
8 | using System;
9 | using System.Collections.Generic;
10 | using System.Diagnostics;
11 | using System.Globalization;
12 | using System.IO;
13 | using System.Linq;
14 | using System.Net;
15 | using System.Runtime.CompilerServices;
16 | using System.Text;
17 | using System.Threading;
18 | using System.Threading.Tasks;
19 | using Windows.Devices.Bluetooth.Advertisement;
20 | using Windows.Gaming.Input;
21 | using Windows.UI.ViewManagement;
22 | using WinUIEx;
23 | using static CommunityToolkit.WinUI.UI.Animations.Expressions.ExpressionValues;
24 | using FortniteLauncher.Pages;
25 | using FortniteLauncher.Services;
26 | using FortniteLauncher.Core.Mods;
27 |
28 | public class Fortnite
29 | {
30 | public static async Task Launch(string GamePath, string Email, string Password)
31 | {
32 | try
33 | {
34 | // Delete the BattlEye folder
35 | //string battlEyeFolderPath = System.IO.Path.Combine(GamePath, "FortniteGame", "Binaries", "Win64", "BattlEye"); // Fully qualify System.IO.Path
36 |
37 | //if (Directory.Exists(battlEyeFolderPath))
38 | {
39 | //Directory.Delete(battlEyeFolderPath, true);
40 | }
41 |
42 | // Delete the FortniteClient-Win64-Shipping_BE.exe file
43 | //string exeFilePath_BE = System.IO.Path.Combine(GamePath, "FortniteGame", "Binaries", "Win64", "FortniteClient-Win64-Shipping_BE.exe"); // Fully qualify System.IO.Path
44 |
45 | //if (File.Exists(exeFilePath_BE))
46 | {
47 | //File.Delete(exeFilePath_BE);
48 | }
49 |
50 | // Delete the FortniteClient-Win64-Shipping_EAC.exe file
51 | //string exeFilePath_EAC = System.IO.Path.Combine(GamePath, "FortniteGame", "Binaries", "Win64", "FortniteClient-Win64-Shipping_EAC.exe"); // Fully qualify System.IO.Path
52 |
53 | //if (File.Exists(exeFilePath_EAC))
54 | {
55 | //File.Delete(exeFilePath_EAC);
56 | }
57 |
58 | WhitelistedProcesses.ProcessCheckLoops();
59 | KillFnProc();
60 | CrashHandler.Start();
61 | //pakcheck(GamePath);
62 | StartLauncherProcesses(GamePath, Email, Password);
63 | PlayPage.STATIC_MainLaunchCard.Header = "Close Exit";
64 | PlayPage.STATIC_MainLaunchCard.Description = "Click here to close Exit. If you're experiencing issues, please restart your computer.";
65 | PlayPage.STATIC_MainLaunchCard.Content = null;
66 | FontIcon icon2 = new FontIcon();
67 | icon2.Glyph = "\uE8BB";
68 | PlayPage.STATIC_MainLaunchCard.HeaderIcon = icon2;
69 | Definitions.BindPlayButton = false;
70 | PlayPage.STATIC_MainLaunchCard.Click += STATIC_MainLaunchCard_CloseClicked;
71 | }
72 | catch (Exception ex)
73 | {
74 | Error();
75 | DialogService.ShowSimpleDialog("Failed to start Fortnite process: " + ex, "Error");
76 | }
77 | }
78 |
79 | public static void Error()
80 | {
81 | KillFnProc();
82 | PlayPage.STATIC_MainLaunchCard.Header = "Launch Season 4";
83 | PlayPage.STATIC_MainLaunchCard.Description = "Launch Fortnite Chapter 2 Season 4 powered by Exit";
84 |
85 | FontIcon icon = new FontIcon();
86 | icon.Glyph = "\uE768";
87 | PlayPage.STATIC_MainLaunchCard.HeaderIcon = icon;
88 | PlayPage.STATIC_MainLaunchCard.Tag = "Launch";
89 | PlayPage.STATIC_MainLaunchCard.Content = null;
90 | Definitions.BindPlayButton = true;
91 | return;
92 | }
93 |
94 | public static void STATIC_MainLaunchCard_CloseClicked(object sender, RoutedEventArgs e)
95 | {
96 | if (!Definitions.BindPlayButton)
97 | {
98 | try
99 | {
100 | Error();
101 | }
102 | catch { }
103 | }
104 | }
105 |
106 | private static async Task StartLauncherProcesses(string gamePath, string email, string password)
107 | {
108 | try
109 | {
110 | Process.Start(new ProcessStartInfo()
111 | {
112 | FileName = gamePath + "\\FortniteGame\\Binaries\\Win64\\FortniteLauncher.exe",
113 | CreateNoWindow = true,
114 | UseShellExecute = false
115 | });
116 |
117 | Process.Start(new ProcessStartInfo()
118 | {
119 | FileName = gamePath + "\\FortniteGame\\Binaries\\Win64\\FortniteClient-Win64-Shipping_BE.exe",
120 | CreateNoWindow = false, // Set to false to show the window
121 | UseShellExecute = false
122 | });
123 |
124 | Process launcherProcess = new Process
125 | {
126 | StartInfo = new ProcessStartInfo(gamePath + "\\EasyAntiCheat\\EasyAntiCheat_EOS_Setup.exe")
127 | {
128 | Arguments = "install \"ef7b6dadbcdf42c6872aa4ad596bbeaf\"",
129 | CreateNoWindow = true,
130 | UseShellExecute = false,
131 | WindowStyle = ProcessWindowStyle.Hidden
132 | }
133 | };
134 | launcherProcess.Start();
135 |
136 | Process gameProcess = new Process
137 | {
138 | StartInfo = new ProcessStartInfo(gamePath + "\\ExitClient-Win64-Shipping.exe")
139 | {
140 | Arguments = $"-AUTH_LOGIN={email} -AUTH_PASSWORD={password} -AUTH_TYPE=epic -epicapp=Fortnite -epicenv=Prod -epiclocale=en-us -epicportal -skippatchcheck -nobe -fltoken=3db3ba5dcbd2e16703f3978d -caldera=eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2NvdW50X2lkIjoiYmU5ZGE1YzJmYmVhNDQw7DBjnzDnXyyEnX7OljJm-j2d88G_WgwQ9wrE6lwMEHZHjBd1ISJdUO1UVUqkfLdU5nofBQ -fromfl=eac",
141 | RedirectStandardOutput = true
142 | }
143 | };
144 | gameProcess.EnableRaisingEvents = true;
145 | gameProcess.Exited += GameProcessExited;
146 | gameProcess.StartInfo.RedirectStandardOutput = true;
147 | gameProcess.StartInfo.UseShellExecute = false;
148 | gameProcess.Start();
149 | }
150 | catch (Exception ex)
151 | {
152 | Error();
153 | DialogService.ShowSimpleDialog("An Error occured while launching Fortnite: " + ex.Message, "Error");
154 | return;
155 | }
156 | }
157 |
158 | static void GameProcessExited(object sender, EventArgs e)
159 | {
160 | KillFnProc();
161 | try
162 | {
163 | //Definitions.MainWindow.Restore(); // it dont work ):
164 | }
165 | catch (Exception ex)
166 | {
167 | //DialogService.ShowSimpleDialog("Error while restoring window: " + ex, "Error"); // DO NOT UNCOMMENT!!!
168 | }
169 | }
170 |
171 | static void KillProcessByName(string processName)
172 | {
173 | Process[] processes = Process.GetProcessesByName(processName);
174 |
175 | foreach (Process process in processes)
176 | {
177 | try
178 | {
179 | process.Kill();
180 | process.WaitForExit();
181 | }
182 | catch
183 | {
184 | }
185 | }
186 | }
187 | public static void KillFnProc()
188 | {
189 | KillProcessByName("FortniteClient-Win64-Shipping");
190 | KillProcessByName("FortniteClient-Win64-Shipping_BE");
191 | KillProcessByName("FortniteClient-Win64-Shipping_EAC");
192 | KillProcessByName("ExitClient-Win64-Shipping");
193 | KillProcessByName("FortniteLauncher");
194 | KillProcessByName("EpicGamesLauncher");
195 | KillProcessByName("CrashReportClient");
196 | }
197 | }
--------------------------------------------------------------------------------
/Core/Loops/AccountCheck.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.UI.Xaml.Controls;
2 | using Microsoft.UI.Xaml.Media;
3 | using Microsoft.UI;
4 | using FortniteLauncher.Pages;
5 | using System;
6 | using System.Collections.Generic;
7 | using System.Linq;
8 | using System.Text;
9 | using System.Threading.Tasks;
10 | using Windows.System;
11 | using Microsoft.UI.Xaml;
12 | using FortniteLauncher.Services;
13 | using System.Runtime.CompilerServices;
14 |
15 | namespace FortniteLauncher.Core.Loops
16 | {
17 | public class AccountCheck
18 | {
19 | public static async Task CheckAccount()
20 | {
21 | try
22 | {
23 | while (true)
24 | {
25 | MongoDB.User user = new MongoDB.User();
26 | if (user != null)
27 | {
28 | if (user.banned)
29 | {
30 | DialogService.ShowSimpleDialog("You have been banned.", "Error");
31 | Fortnite.KillFnProc();
32 |
33 | await Task.Delay(250);
34 |
35 | MainWindow.ShellFrame.Navigate(typeof(LoginPage));
36 | }
37 | } else
38 | {
39 | DialogService.ShowSimpleDialog("Error user is null", "Error");
40 | Fortnite.KillFnProc();
41 | await Task.Delay(250);
42 |
43 | MainWindow.ShellFrame.Navigate(typeof(LoginPage));
44 | }
45 | await Task.Delay(1000);
46 | }
47 | } catch { }
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/Core/Mods/Anticheat.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.UI.Xaml.Controls;
2 | using Microsoft.UI.Xaml.Media;
3 | using Microsoft.UI.Xaml;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Diagnostics;
7 | using System.IO;
8 | using System.IO.Compression;
9 | using System.Linq;
10 | using System.Net;
11 | using System.Threading.Tasks;
12 | using System.Threading;
13 | using FortniteLauncher.Pages;
14 | using FortniteLauncher.Services;
15 | using FortniteLauncher.Core.Mods;
16 | using FortniteLauncher.Pages;
17 | using FortniteLauncher.Services;
18 | using SharpCompress.Archives;
19 | using Windows.ApplicationModel;
20 |
21 | public class Anticheat
22 | {
23 | public static async Task CheckForMods(string FNPath)
24 | {
25 | if (Directory.Exists(FNPath))
26 | {
27 | if (Directory.Exists(Path.Combine(FNPath, "FortniteGame", "Content", "Paks")))
28 | {
29 | string directoryPath = Path.Combine(FNPath, "FortniteGame", "Content", "Paks");
30 |
31 | // S14.60
32 | string[] expectedFiles = new string[]
33 | {
34 | Path.Combine(directoryPath, "global.ucas"),
35 | Path.Combine(directoryPath, "global.utoc"),
36 | Path.Combine(directoryPath, "pakchunk0optional-WindowsClient.pak"),
37 | Path.Combine(directoryPath, "pakchunk0optional-WindowsClient.sig"),
38 | Path.Combine(directoryPath, "pakchunk0optional-WindowsClient.ucas"),
39 | Path.Combine(directoryPath, "pakchunk0optional-WindowsClient.utoc"),
40 | Path.Combine(directoryPath, "pakchunk0-WindowsClient.pak"),
41 | Path.Combine(directoryPath, "pakchunk0-WindowsClient.sig"),
42 | Path.Combine(directoryPath, "pakchunk0-WindowsClient.ucas"),
43 | Path.Combine(directoryPath, "pakchunk0-WindowsClient.utoc"),
44 | Path.Combine(directoryPath, "pakchunk2-WindowsClient.pak"),
45 | Path.Combine(directoryPath, "pakchunk2-WindowsClient.sig"),
46 | Path.Combine(directoryPath, "pakchunk2-WindowsClient.ucas"),
47 | Path.Combine(directoryPath, "pakchunk2-WindowsClient.utoc"),
48 | Path.Combine(directoryPath, "pakchunk5-WindowsClient.pak"),
49 | Path.Combine(directoryPath, "pakchunk5-WindowsClient.sig"),
50 | Path.Combine(directoryPath, "pakchunk5-WindowsClient.ucas"),
51 | Path.Combine(directoryPath, "pakchunk5-WindowsClient.utoc"),
52 | Path.Combine(directoryPath, "pakchunk7-WindowsClient.pak"),
53 | Path.Combine(directoryPath, "pakchunk7-WindowsClient.sig"),
54 | Path.Combine(directoryPath, "pakchunk7-WindowsClient.ucas"),
55 | Path.Combine(directoryPath, "pakchunk7-WindowsClient.utoc"),
56 | Path.Combine(directoryPath, "pakchunk8-WindowsClient.pak"),
57 | Path.Combine(directoryPath, "pakchunk8-WindowsClient.sig"),
58 | Path.Combine(directoryPath, "pakchunk8-WindowsClient.ucas"),
59 | Path.Combine(directoryPath, "pakchunk8-WindowsClient.utoc"),
60 | Path.Combine(directoryPath, "pakchunk9-WindowsClient.pak"),
61 | Path.Combine(directoryPath, "pakchunk9-WindowsClient.sig"),
62 | Path.Combine(directoryPath, "pakchunk9-WindowsClient.ucas"),
63 | Path.Combine(directoryPath, "pakchunk9-WindowsClient.utoc"),
64 | Path.Combine(directoryPath, "pakchunk10_s1-WindowsClient.pak"),
65 | Path.Combine(directoryPath, "pakchunk10_s1-WindowsClient.sig"),
66 | Path.Combine(directoryPath, "pakchunk10_s1-WindowsClient.ucas"),
67 | Path.Combine(directoryPath, "pakchunk10_s1-WindowsClient.utoc"),
68 | Path.Combine(directoryPath, "pakchunk10_s2-WindowsClient.pak"),
69 | Path.Combine(directoryPath, "pakchunk10_s2-WindowsClient.sig"),
70 | Path.Combine(directoryPath, "pakchunk10_s2-WindowsClient.ucas"),
71 | Path.Combine(directoryPath, "pakchunk10_s2-WindowsClient.utoc"),
72 | Path.Combine(directoryPath, "pakchunk10_s3-WindowsClient.pak"),
73 | Path.Combine(directoryPath, "pakchunk10_s3-WindowsClient.sig"),
74 | Path.Combine(directoryPath, "pakchunk10_s3-WindowsClient.ucas"),
75 | Path.Combine(directoryPath, "pakchunk10_s3-WindowsClient.utoc"),
76 | Path.Combine(directoryPath, "pakchunk10_s4-WindowsClient.pak"),
77 | Path.Combine(directoryPath, "pakchunk10_s4-WindowsClient.sig"),
78 | Path.Combine(directoryPath, "pakchunk10_s4-WindowsClient.ucas"),
79 | Path.Combine(directoryPath, "pakchunk10_s4-WindowsClient.utoc"),
80 | Path.Combine(directoryPath, "pakchunk10_s5-WindowsClient.pak"),
81 | Path.Combine(directoryPath, "pakchunk10_s5-WindowsClient.sig"),
82 | Path.Combine(directoryPath, "pakchunk10_s5-WindowsClient.ucas"),
83 | Path.Combine(directoryPath, "pakchunk10_s5-WindowsClient.utoc"),
84 | Path.Combine(directoryPath, "pakchunk10_s6-WindowsClient.pak"),
85 | Path.Combine(directoryPath, "pakchunk10_s6-WindowsClient.sig"),
86 | Path.Combine(directoryPath, "pakchunk10_s6-WindowsClient.ucas"),
87 | Path.Combine(directoryPath, "pakchunk10_s6-WindowsClient.utoc"),
88 | Path.Combine(directoryPath, "pakchunk10_s7-WindowsClient.pak"),
89 | Path.Combine(directoryPath, "pakchunk10_s7-WindowsClient.sig"),
90 | Path.Combine(directoryPath, "pakchunk10_s7-WindowsClient.ucas"),
91 | Path.Combine(directoryPath, "pakchunk10_s7-WindowsClient.utoc"),
92 | Path.Combine(directoryPath, "pakchunk10_s8-WindowsClient.pak"),
93 | Path.Combine(directoryPath, "pakchunk10_s8-WindowsClient.sig"),
94 | Path.Combine(directoryPath, "pakchunk10_s8-WindowsClient.ucas"),
95 | Path.Combine(directoryPath, "pakchunk10_s8-WindowsClient.utoc"),
96 | Path.Combine(directoryPath, "pakchunk10_s9-WindowsClient.pak"),
97 | Path.Combine(directoryPath, "pakchunk10_s9-WindowsClient.sig"),
98 | Path.Combine(directoryPath, "pakchunk10_s9-WindowsClient.ucas"),
99 | Path.Combine(directoryPath, "pakchunk10_s9-WindowsClient.utoc"),
100 | Path.Combine(directoryPath, "pakchunk10_s10-WindowsClient.pak"),
101 | Path.Combine(directoryPath, "pakchunk10_s10-WindowsClient.sig"),
102 | Path.Combine(directoryPath, "pakchunk10_s10-WindowsClient.ucas"),
103 | Path.Combine(directoryPath, "pakchunk10_s10-WindowsClient.utoc"),
104 | Path.Combine(directoryPath, "pakchunk10_s11-WindowsClient.pak"),
105 | Path.Combine(directoryPath, "pakchunk10_s11-WindowsClient.sig"),
106 | Path.Combine(directoryPath, "pakchunk10_s11-WindowsClient.ucas"),
107 | Path.Combine(directoryPath, "pakchunk10_s11-WindowsClient.utoc"),
108 | Path.Combine(directoryPath, "pakchunk10_s12-WindowsClient.pak"),
109 | Path.Combine(directoryPath, "pakchunk10_s12-WindowsClient.sig"),
110 | Path.Combine(directoryPath, "pakchunk10_s12-WindowsClient.ucas"),
111 | Path.Combine(directoryPath, "pakchunk10_s12-WindowsClient.utoc"),
112 | Path.Combine(directoryPath, "pakchunk10_s13-WindowsClient.pak"),
113 | Path.Combine(directoryPath, "pakchunk10_s13-WindowsClient.sig"),
114 | Path.Combine(directoryPath, "pakchunk10_s13-WindowsClient.ucas"),
115 | Path.Combine(directoryPath, "pakchunk10_s13-WindowsClient.utoc"),
116 | Path.Combine(directoryPath, "pakchunk10_s14-WindowsClient.pak"),
117 | Path.Combine(directoryPath, "pakchunk10_s14-WindowsClient.sig"),
118 | Path.Combine(directoryPath, "pakchunk10_s14-WindowsClient.ucas"),
119 | Path.Combine(directoryPath, "pakchunk10_s14-WindowsClient.utoc"),
120 | Path.Combine(directoryPath, "pakchunk10_s15-WindowsClient.pak"),
121 | Path.Combine(directoryPath, "pakchunk10_s15-WindowsClient.sig"),
122 | Path.Combine(directoryPath, "pakchunk10_s15-WindowsClient.ucas"),
123 | Path.Combine(directoryPath, "pakchunk10_s15-WindowsClient.utoc"),
124 | Path.Combine(directoryPath, "pakchunk10_s16-WindowsClient.pak"),
125 | Path.Combine(directoryPath, "pakchunk10_s16-WindowsClient.sig"),
126 | Path.Combine(directoryPath, "pakchunk10_s16-WindowsClient.ucas"),
127 | Path.Combine(directoryPath, "pakchunk10_s16-WindowsClient.utoc"),
128 | Path.Combine(directoryPath, "pakchunk10_s17-WindowsClient.pak"),
129 | Path.Combine(directoryPath, "pakchunk10_s17-WindowsClient.sig"),
130 | Path.Combine(directoryPath, "pakchunk10_s17-WindowsClient.ucas"),
131 | Path.Combine(directoryPath, "pakchunk10_s17-WindowsClient.utoc"),
132 | Path.Combine(directoryPath, "pakchunk10_s18-WindowsClient.pak"),
133 | Path.Combine(directoryPath, "pakchunk10_s18-WindowsClient.sig"),
134 | Path.Combine(directoryPath, "pakchunk10_s18-WindowsClient.ucas"),
135 | Path.Combine(directoryPath, "pakchunk10_s18-WindowsClient.utoc"),
136 | Path.Combine(directoryPath, "pakchunk10_s19-WindowsClient.pak"),
137 | Path.Combine(directoryPath, "pakchunk10_s19-WindowsClient.sig"),
138 | Path.Combine(directoryPath, "pakchunk10_s19-WindowsClient.ucas"),
139 | Path.Combine(directoryPath, "pakchunk10_s19-WindowsClient.utoc"),
140 | Path.Combine(directoryPath, "pakchunk10_s20-WindowsClient.pak"),
141 | Path.Combine(directoryPath, "pakchunk10_s20-WindowsClient.sig"),
142 | Path.Combine(directoryPath, "pakchunk10_s20-WindowsClient.ucas"),
143 | Path.Combine(directoryPath, "pakchunk10_s20-WindowsClient.utoc"),
144 | Path.Combine(directoryPath, "pakchunk10_s21-WindowsClient.pak"),
145 | Path.Combine(directoryPath, "pakchunk10_s21-WindowsClient.sig"),
146 | Path.Combine(directoryPath, "pakchunk10_s21-WindowsClient.ucas"),
147 | Path.Combine(directoryPath, "pakchunk10_s21-WindowsClient.utoc"),
148 | Path.Combine(directoryPath, "pakchunk10-WindowsClient.pak"),
149 | Path.Combine(directoryPath, "pakchunk10-WindowsClient.sig"),
150 | Path.Combine(directoryPath, "pakchunk10-WindowsClient.ucas"),
151 | Path.Combine(directoryPath, "pakchunk10-WindowsClient.utoc"),
152 | Path.Combine(directoryPath, "pakchunk11_s1-WindowsClient.pak"),
153 | Path.Combine(directoryPath, "pakchunk11_s1-WindowsClient.sig"),
154 | Path.Combine(directoryPath, "pakchunk11_s1-WindowsClient.ucas"),
155 | Path.Combine(directoryPath, "pakchunk11_s1-WindowsClient.utoc"),
156 | Path.Combine(directoryPath, "pakchunk11-WindowsClient.pak"),
157 | Path.Combine(directoryPath, "pakchunk11-WindowsClient.sig"),
158 | Path.Combine(directoryPath, "pakchunk11-WindowsClient.ucas"),
159 | Path.Combine(directoryPath, "pakchunk11-WindowsClient.utoc"),
160 | Path.Combine(directoryPath, "pakchunk1000-WindowsClient.pak"),
161 | Path.Combine(directoryPath, "pakchunk1000-WindowsClient.sig"),
162 | Path.Combine(directoryPath, "pakchunk1000-WindowsClient.ucas"),
163 | Path.Combine(directoryPath, "pakchunk1000-WindowsClient.utoc"),
164 | Path.Combine(directoryPath, "pakchunk1001-WindowsClient.pak"),
165 | Path.Combine(directoryPath, "pakchunk1001-WindowsClient.sig"),
166 | Path.Combine(directoryPath, "pakchunk1001-WindowsClient.ucas"),
167 | Path.Combine(directoryPath, "pakchunk1001-WindowsClient.utoc"),
168 | Path.Combine(directoryPath, "pakchunk1002-WindowsClient.pak"),
169 | Path.Combine(directoryPath, "pakchunk1002-WindowsClient.sig"),
170 | Path.Combine(directoryPath, "pakchunk1002-WindowsClient.ucas"),
171 | Path.Combine(directoryPath, "pakchunk1002-WindowsClient.utoc"),
172 | Path.Combine(directoryPath, "pakchunk1003-WindowsClient.pak"),
173 | Path.Combine(directoryPath, "pakchunk1003-WindowsClient.sig"),
174 | Path.Combine(directoryPath, "pakchunk1003-WindowsClient.ucas"),
175 | Path.Combine(directoryPath, "pakchunk1003-WindowsClient.utoc"),
176 | Path.Combine(directoryPath, "pakchunk1004-WindowsClient.pak"),
177 | Path.Combine(directoryPath, "pakchunk1004-WindowsClient.sig"),
178 | Path.Combine(directoryPath, "pakchunk1004-WindowsClient.ucas"),
179 | Path.Combine(directoryPath, "pakchunk1004-WindowsClient.utoc"),
180 | Path.Combine(directoryPath, "pakchunk1005-WindowsClient.pak"),
181 | Path.Combine(directoryPath, "pakchunk1005-WindowsClient.sig"),
182 | Path.Combine(directoryPath, "pakchunk1005-WindowsClient.ucas"),
183 | Path.Combine(directoryPath, "pakchunk1005-WindowsClient.utoc"),
184 | Path.Combine(directoryPath, "pakchunk1006-WindowsClient.pak"),
185 | Path.Combine(directoryPath, "pakchunk1006-WindowsClient.sig"),
186 | Path.Combine(directoryPath, "pakchunk1006-WindowsClient.ucas"),
187 | Path.Combine(directoryPath, "pakchunk1006-WindowsClient.utoc"),
188 | Path.Combine(directoryPath, "pakchunk1007-WindowsClient.pak"),
189 | Path.Combine(directoryPath, "pakchunk1007-WindowsClient.sig"),
190 | Path.Combine(directoryPath, "pakchunk1007-WindowsClient.ucas"),
191 | Path.Combine(directoryPath, "pakchunk1007-WindowsClient.utoc"),
192 | Path.Combine(directoryPath, "pakChunkEarly-WindowsClient.pak"),
193 | Path.Combine(directoryPath, "pakChunkEarly-WindowsClient.sig"),
194 | Path.Combine(directoryPath, "pakChunkEarly-WindowsClient.ucas"),
195 | Path.Combine(directoryPath, "pakChunkEarly-WindowsClient.utoc"),
196 | };
197 |
198 | string[] filesInDirectory = Directory.GetFiles(directoryPath);
199 |
200 | bool hasUnexpectedFiles = false;
201 | long totalSize = 0;
202 | List unexpectedFiles = new List();
203 | foreach (string filePath in filesInDirectory)
204 | {
205 | if (Array.IndexOf(expectedFiles, filePath) == -1)
206 | {
207 | unexpectedFiles.Add(filePath);
208 | if (unexpectedFiles.Count > 5)
209 | {
210 | DialogService.ShowSimpleDialog("Many files are missing please make sure you have selected a 14.60 build.", "Error");
211 | return "Error";
212 | }
213 | Fortnite.KillFnProc();
214 | bool result = await DialogService.YesOrNoDialog($"Exit does not support playing with modded paks. Would you like to remove the listed file(s)? {Environment.NewLine} {string.Join(", ", unexpectedFiles)}", "Modified Client");
215 | if (result)
216 | {
217 | try
218 | {
219 | foreach (string unexpectedFile in unexpectedFiles)
220 | {
221 | File.Delete(unexpectedFile);
222 | }
223 | }
224 | catch { }
225 | }
226 |
227 | hasUnexpectedFiles = true;
228 | return "Error";
229 | }
230 | else
231 | {
232 | FileInfo fileInfo = new FileInfo(filePath);
233 | totalSize += fileInfo.Length;
234 | }
235 | }
236 |
237 | long expectedSize = 97881153484;
238 |
239 | if (hasUnexpectedFiles)
240 | {
241 | Fortnite.KillFnProc();
242 | Console.WriteLine("Error: There are unexpected files in the directory.");
243 | return "Error";
244 | }
245 | else
246 | {
247 | if (totalSize == expectedSize)
248 | {
249 | return "Success";
250 | }
251 | else
252 | {
253 | Fortnite.KillFnProc();
254 | DialogService.ShowSimpleDialog($"Pak check failed invalid size.", "Error");
255 | return "Error";
256 | }
257 | }
258 | }
259 | else
260 | {
261 | Fortnite.KillFnProc();
262 | DialogService.ShowSimpleDialog("Failed to launch Fortnite. Paks directory not found.", "Error");
263 | return "Error";
264 | }
265 | }
266 | else
267 | {
268 | Fortnite.KillFnProc();
269 | DialogService.ShowSimpleDialog("Fortnite path is empty. Please check your settings and try again.", "Error");
270 | return "Error";
271 | }
272 | }
273 |
274 | public static async Task VerifyClient(string FNPath)
275 | {
276 | try
277 | {
278 | string[] requiredPaths = new string[]
279 | {
280 | Path.Combine(FNPath, "ExitClient-Win64-Shipping.exe"),
281 | Path.Combine(FNPath, "EasyAntiCheat", "Certificates"),
282 | Path.Combine(FNPath, "EasyAntiCheat", "Licenses"),
283 | Path.Combine(FNPath, "EasyAntiCheat", "Localization"),
284 | Path.Combine(FNPath, "EasyAntiCheat", "EasyAntiCheat_EOS_Setup.exe"),
285 | Path.Combine(FNPath, "EasyAntiCheat", "Settings.json"),
286 | Path.Combine(FNPath, "EasyAntiCheat", "SplashScreen.png")
287 | };
288 | try
289 | {
290 | if (File.Exists(FNPath + "\\FortniteGame\\Binaries\\Win64\\FortniteClient-Win64-Shipping_BE.exe") || !File.Exists(FNPath + "\\FortniteGame\\Binaries\\Win64\\FortniteClient-Win64-Shipping_BE.exe"))
291 | {
292 | File.Delete(FNPath + "\\FortniteGame\\Binaries\\Win64\\FortniteClient-Win64-Shipping_BE.exe");
293 | await DownloadFile.DownloadFiles(Definitions.BELauncherurl, FNPath + "\\FortniteGame\\Binaries\\Win64\\FortniteClient-Win64-Shipping_BE.exe");
294 | }
295 |
296 | if (File.Exists(FNPath + "\\FortniteGame\\Binaries\\Win64\\FortniteLauncher.exe") || !File.Exists(FNPath + "\\FortniteGame\\Binaries\\Win64\\FortniteLauncher.exe"))
297 | {
298 | File.Delete(FNPath + "\\FortniteGame\\Binaries\\Win64\\FortniteLauncher.exe");
299 | await DownloadFile.DownloadFiles(Definitions.Launcherurl, FNPath + "\\FortniteGame\\Binaries\\Win64\\FortniteLauncher.exe");
300 | }
301 |
302 |
303 | File.Delete(FNPath + "\\Engine\\Binaries\\ThirdParty\\NVIDIA\\NVaftermath\\Win64\\GFSDK_Aftermath_Lib.x64.dll");
304 | await DownloadFile.DownloadFiles(Definitions.RedirectUrl, FNPath + "\\Engine\\Binaries\\ThirdParty\\NVIDIA\\NVaftermath\\Win64\\GFSDK_Aftermath_Lib.x64.dll");
305 | if (!File.Exists(Definitions.RootDirectory + "\\Assets\\MemoryLeakFixer.dll"))
306 | {
307 | if (!Directory.Exists(Definitions.RootDirectory + "\\Assets"))
308 | {
309 | Directory.CreateDirectory(Definitions.RootDirectory + "\\Assets");
310 | }
311 | //await DownloadFile.DownloadFiles(Definitions.ExitMemoryLeakFixer, Definitions.RootDirectory + "\\Assets\\MemoryLeakFixer.dll");
312 | }
313 | }
314 | catch { }
315 | //Scan(FNPath);
316 | foreach (string path in requiredPaths)
317 | {
318 | if (!Directory.Exists(path) && !File.Exists(path))
319 | {
320 | await PatchClient(FNPath);
321 | return true;
322 | }
323 | }
324 |
325 | File.Delete(FNPath + "\\EasyAntiCheat\\SplashScreen.png");
326 | File.Delete(FNPath + "\\EasyAntiCheat\\Settings.json");
327 |
328 | using (WebClient client = new WebClient())
329 | {
330 | if (Definitions.ExitSplashScreen == null || Definitions.ExitSettingsJson == null)
331 | {
332 | //await LoginPage.GetDownloads();
333 | client.DownloadFile(Definitions.ExitSplashScreen, FNPath + "\\EasyAntiCheat\\SplashScreen.png");
334 | client.DownloadFile(Definitions.ExitSettingsJson, FNPath + "\\EasyAntiCheat\\Settings.json");
335 | }
336 | else
337 | {
338 | client.DownloadFile(Definitions.ExitSplashScreen, FNPath + "\\EasyAntiCheat\\SplashScreen.png");
339 | client.DownloadFile(Definitions.ExitSettingsJson, FNPath + "\\EasyAntiCheat\\Settings.json");
340 | }
341 | }
342 | }
343 | catch (Exception ex)
344 | {
345 | DialogService.ShowSimpleDialog("Error while verifying files: " + ex.Message, "Error");
346 | return false;
347 | }
348 |
349 | return true;
350 | }
351 |
352 | static async Task DownloadEACPatch(string FNPath)
353 | {
354 | try
355 | {
356 | string url = Definitions.AntiCheatUrl;
357 | string downloadPath = Definitions.RootDirectory + "\\EAC";
358 |
359 | if (!Directory.Exists(downloadPath))
360 | {
361 | Directory.CreateDirectory(downloadPath);
362 | }
363 |
364 | string extractionPath = FNPath;
365 |
366 | using (WebClient client = new WebClient())
367 | {
368 | client.DownloadFile(url, Path.Combine(downloadPath, "EasyAntiCheat.zip"));
369 | }
370 |
371 | ZipFile.ExtractToDirectory(Path.Combine(downloadPath, "EasyAntiCheat.zip"), extractionPath);
372 | }
373 | catch (WebException ex)
374 | {
375 | DialogService.ShowSimpleDialog("Failed to download required files: " + ex.Message, "Webclient Error");
376 | return;
377 | }
378 | }
379 |
380 | static void StartPatching()
381 | {
382 | PlayPage.STATIC_MainLaunchCard.Header = "Patching Fortnite";
383 | PlayPage.STATIC_MainLaunchCard.Description = "Downloading required files...";
384 | }
385 |
386 | public static async Task PatchClient(string FNPath)
387 | {
388 | try
389 | {
390 | ProgressRing loading = new ProgressRing();
391 | loading.IsIndeterminate = true;
392 | loading.Foreground = new SolidColorBrush(Microsoft.UI.Colors.Black);
393 | loading.HorizontalAlignment = HorizontalAlignment.Center;
394 |
395 | StartPatching();
396 |
397 | PlayPage.STATIC_MainLaunchCard.Content = loading;
398 | await Task.Delay(1000);
399 | Fortnite.KillFnProc();
400 |
401 | if (Directory.Exists(FNPath + "\\EasyAntiCheat"))
402 | {
403 | Directory.Delete(FNPath + "\\EasyAntiCheat", true);
404 | }
405 |
406 | if (File.Exists(FNPath + "\\ExitClient-Win64-Shipping.exe"))
407 | {
408 | File.Delete(FNPath + "\\ExitClient-Win64-Shipping.exe");
409 | }
410 |
411 | await DownloadEACPatch(FNPath);
412 | string downloadPath = Definitions.RootDirectory + "\\EAC";
413 |
414 | if (Directory.Exists(downloadPath))
415 | {
416 | Directory.Delete(downloadPath, true);
417 | }
418 |
419 | if (File.Exists(downloadPath + "\\EasyAntiCheat.zip"))
420 | {
421 | File.Delete(downloadPath + "\\EasyAntiCheat.zip");
422 | }
423 | return "Success";
424 | }
425 | catch (WebException ex)
426 | {
427 | DialogService.ShowSimpleDialog("An error occurred while installing zip: " + ex.Message, "Error");
428 | return "Error";
429 | }
430 | }
431 | }
--------------------------------------------------------------------------------
/Core/Mods/DownloadFile.cs:
--------------------------------------------------------------------------------
1 | using FortniteLauncher.Pages;
2 | using System;
3 | using System.Diagnostics;
4 | using System.IO;
5 | using System.IO.Compression;
6 | using System.Net;
7 | using System.Threading.Tasks;
8 |
9 | namespace FortniteLauncher.Core.Mods
10 | {
11 | internal class DownloadFile
12 | {
13 | public static async Task DownloadFiles(string URL, string path, IProgress progress = null)
14 | {
15 | try
16 | {
17 | using (var webClient = new WebClient())
18 | {
19 | if (progress != null)
20 | {
21 | webClient.DownloadProgressChanged += (sender, e) =>
22 | {
23 | double percentage = (double)e.BytesReceived / e.TotalBytesToReceive * 100;
24 | progress.Report(percentage);
25 | };
26 | }
27 |
28 | webClient.DownloadFileAsync(new Uri(URL), path);
29 | }
30 | }
31 | catch (WebException ex)
32 | {
33 | Debug.WriteLine("Error while installing required files: " + ex.Message, "WebClient Error");
34 | }
35 | }
36 |
37 | public static async Task WaitForFileToBeReleased(string filePath)
38 | {
39 | while (IsFileLocked(filePath))
40 | {
41 | await Task.Delay(100); // Delay to avoid busy-waiting
42 | }
43 | }
44 |
45 | public static bool IsFileLocked(string filePath)
46 | {
47 | try
48 | {
49 | using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.None))
50 | {
51 | // If the file can be opened with no sharing, it's not locked
52 | }
53 | }
54 | catch (IOException)
55 | {
56 | // The file is locked
57 | return true;
58 | }
59 |
60 | // The file is not locked
61 | return false;
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/Core/Mods/WhitelistedProcesses.cs:
--------------------------------------------------------------------------------
1 | using FortniteLauncher.Services;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Diagnostics;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Text.RegularExpressions;
8 | using System.Threading.Tasks;
9 | using Windows.Networking;
10 |
11 | namespace FortniteLauncher.Core.Mods
12 | {
13 | internal class WhitelistedProcesses
14 | {
15 | public static List BlockedApps = new List
16 | {
17 | "ida64", "IDAPortable", "OllyDbg", "x64dbg", "Cheat Engine",
18 | "Ghidra", "Binary Ninja", "Radare2", "Hopper", "IDA Free", "PEiD", "Exeinfo PE",
19 | "Procmon", "Wireshark", "Fiddler", "Charles Proxy", "Burp Suite", "ZAP Proxy",
20 | "Wireshark", "Telerik Fiddler", "WiX Toolset", "NSIS", "Inno Setup", "Nullsoft Scriptable Install System",
21 | "Dependency Walker", "PE Explorer", "Resource Hacker", "dnSpy", "ILSpy", "Reflector",
22 | "Eclipse", "PyCharm", "Vim", "WinHex", "Hex Fiend", "Hex Workshop", "IDA Free", "BinaryDiff", "OllyICE",
23 | "GameGuardian", "Memory Editors", "Debuggers", "Disassemblers", "Packet Sniffers", "Proxy Tools", "UuuClient", "ProcessHacker", "Wemod"
24 |
25 | };
26 | public static async Task ProcessCheckLoops()
27 | {
28 | bool done = false;
29 | while (!done)
30 | {
31 | foreach (var process in Process.GetProcesses())
32 | {
33 | string processName = process.ProcessName.ToLower();
34 | if (BlockedApps.Contains(processName))
35 | {
36 | Fortnite.Error();
37 | DialogService.ShowSimpleDialog("A whitelisted process is running please close: " + processName + " before playing Exit.", "Error");
38 | break;
39 | }
40 | }
41 | await Task.Delay(1000);
42 | }
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/Core/MongDB/MongoDB.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using MongoDB.Bson.Serialization.Attributes;
3 | using MongoDB.Bson;
4 | using MongoDB.Driver;
5 | using System.Threading.Tasks;
6 | using FortniteLauncher.Pages;
7 | using FortniteLauncher.Services;
8 | using MongoDB.Driver.Core.Authentication;
9 | using FortniteLauncher.Core.Loops;
10 | using Microsoft.UI.Xaml;
11 | using CommunityToolkit.WinUI.Helpers;
12 |
13 | namespace FortniteLauncher.MongoDB
14 | {
15 | public static class MongoDBAuthenticator
16 | {
17 | public static async Task CheckLogin(string email, string password)
18 | {
19 | try
20 | {
21 | string cng = await API.MongoDBConnectionString();
22 | // MongoDB connection string
23 | if (cng == null)
24 | {
25 | return null;
26 | } else
27 | {
28 | string connectionString = cng;
29 |
30 | // MongoDB client
31 | var client = new MongoClient(connectionString);
32 |
33 | // Access the database
34 | var database = client.GetDatabase("Put your backend name here ig i removed mine so people dont hack it");
35 |
36 | // Access the collection
37 | var collection = database.GetCollection("users");
38 |
39 | //DialogService.CurcleLoading("Hello");
40 | // Call VerifyLoginAsync to handle login verification
41 | return await VerifyLoginAsync(collection, email, password);
42 | }
43 |
44 | }
45 | catch (Exception ex)
46 | {
47 | // Properly handle the exception, don't ignore it.
48 | DialogService.ShowSimpleDialog("An Error occurred while Authenticating: " + ex.Message, "Error");
49 | return "Error";
50 | }
51 | }
52 | public static async Task VerifyLoginAsync(IMongoCollection collection, string email, string password)
53 | {
54 | try
55 | {
56 | // Query the collection to find the user with the given email
57 | var filter = Builders.Filter.Eq(u => u.email, email);
58 | var user = await collection.Find(filter).SingleOrDefaultAsync();
59 |
60 | if (user != null)
61 | {
62 | // Check if the user is banned
63 | if (user.banned)
64 | {
65 | return "Banned";
66 | }
67 |
68 | if (user.Reports > 5)
69 | {
70 | return "Deny";
71 | }
72 | // Verify the provided password against the stored hashed password using bcrypt
73 | bool isPasswordValid = VerifyPassword(password, user.password);
74 |
75 | if (!isPasswordValid)
76 | {
77 | return "Invalid";
78 | }
79 | else
80 | {
81 | if (user.username == null)
82 | {
83 | return "Error";
84 | }
85 | else
86 | {
87 | Definitions.UserName = user.username;
88 | Definitions.Email = email;
89 | Definitions.Password = password;
90 | MainShellPage.DisplayUsername = user.username.ToString();
91 | AccountCheck.CheckAccount();
92 | return "Success";
93 | }
94 |
95 | }
96 | }
97 | else
98 | {
99 | return "Invalid";
100 | }
101 | }
102 | catch (Exception ex)
103 | {
104 | DialogService.ShowSimpleDialog("An Error occurred while Authenticating: " + ex.Message, "Error");
105 | return "Error";
106 | }
107 | }
108 |
109 | // Function to verify the provided password against the stored hashed password using bcrypt
110 | public static bool VerifyPassword(string password, string storedHashedPassword)
111 | {
112 | return BCrypt.Net.BCrypt.Verify(password, storedHashedPassword);
113 | }
114 | }
115 |
116 | // Define a User class that represents the MongoDB document in the "users" collection
117 | public class User
118 | {
119 | [BsonId]
120 | public ObjectId Id { get; set; }
121 | public DateTime created { get; set; }
122 | public bool banned { get; set; }
123 | public string discordId { get; set; }
124 | public string accountId { get; set; }
125 | public string username { get; set; }
126 | public string username_lower { get; set; }
127 | public string email { get; set; }
128 | public string password { get; set; }
129 | public bool mfa { get; set; }
130 | public string matchmakingId { get; set; }
131 | public bool canCreateCodes { get; set; }
132 | public bool isServer { get; set; }
133 | public bool GivenFullLocker { get; set; }
134 | public int Reports { get; set; }
135 | public int __v { get; set; }
136 | }
137 | }
138 |
--------------------------------------------------------------------------------
/Core/Settings.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.UI.Xaml;
2 | using Newtonsoft.Json;
3 | using FortniteLauncher.Interop;
4 | using FortniteLauncher.Services;
5 | using System;
6 | using System.IO;
7 | using System.Threading.Tasks;
8 | using Windows.Media.DialProtocol;
9 | using Windows.Storage;
10 |
11 | namespace FortniteLauncher.Core
12 | {
13 | public class Settings
14 | {
15 | private static string RootDirectory = Definitions.RootDirectory;
16 | private static string SaveFile = Path.Combine(RootDirectory, "settings.json");
17 |
18 | public static void SaveSettings()
19 | {
20 | var json = JsonConvert.SerializeObject(Globals.m_config);
21 |
22 | if (!Directory.Exists(RootDirectory))
23 | {
24 | Directory.CreateDirectory(RootDirectory);
25 | }
26 |
27 | using (var fileStream = new FileStream(SaveFile, FileMode.Create, FileAccess.Write))
28 | {
29 | using (var writer = new StreamWriter(fileStream))
30 | {
31 | writer.Write(json);
32 | }
33 | }
34 | }
35 |
36 | public static void LoadSettings()
37 | {
38 | try
39 | {
40 | if (File.Exists(SaveFile))
41 | {
42 | using (var fileStream = new FileStream(SaveFile, FileMode.Open, FileAccess.Read))
43 | {
44 | using (var reader = new StreamReader(fileStream))
45 | {
46 | string json = reader.ReadToEnd();
47 | Config config = JsonConvert.DeserializeObject(json);
48 | Globals.m_config = config;
49 | }
50 | }
51 | }
52 | else
53 | {
54 | // File not found, set default values
55 | Globals.m_config = new Config
56 | {
57 | IsSoundEnabled = false,
58 | };
59 |
60 | SaveSettings();
61 | }
62 | }
63 | catch (Exception ex)
64 | {
65 | //we cannot show a dialog, it might cause a crash as the main window is not loaded yet
66 | MessageBox.Show("An Error occured while loading settings: " + ex.Message, "Error");
67 | }
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/Core/Updates/CheckForUpdates.cs:
--------------------------------------------------------------------------------
1 | using FortniteLauncher.Services;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading;
7 | using System.Threading.Tasks;
8 |
9 | public class CheckForUpdatesAPI
10 | {
11 | public static string CurrentVersion = Definitions.CurrentVersion;
12 |
13 | public static async Task Start()
14 | {
15 | string connection = await API.Connect();
16 | string apiver = await API.Version();
17 | if (connection == "Success")
18 | {
19 | Definitions.APIversion = apiver;
20 | checkforupdatesAsync();
21 | } else if (connection == "Error")
22 | {
23 | DialogService.ShowSimpleDialog("An Error occured while checking for updates.", "Error");
24 | } else
25 | {
26 | DialogService.ShowSimpleDialog("Unknown API data returned.", "Error");
27 | }
28 | }
29 |
30 | public static async Task checkforupdatesAsync()
31 | {
32 | if (Definitions.APIversion != CurrentVersion)
33 | {
34 | DialogService.ShowSimpleDialog("A new update was detected latest version: " + Definitions.APIversion + " current version: " + Definitions.CurrentVersion, "outdated");
35 | Definitions.outdated = true;
36 | return Definitions.APIversion != CurrentVersion;
37 | } else
38 | {
39 | return true;
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/Core/def/Definitions.cs:
--------------------------------------------------------------------------------
1 | using MongoDB.Bson.IO;
2 | using FortniteLauncher;
3 | using System;
4 |
5 | internal class Definitions
6 | {
7 | // put all of your shit here so it automaticly downloads and redirects and shit
8 | public static string CurrentVersion = "1.0.0";
9 | public static string APIurl = "http://yourip:yourport/v1/";
10 | public static string RootDirectory = Environment.GetEnvironmentVariable("LocalAppData") + "\\FortniteLauncher";
11 | public static string BELauncherurl = "";
12 | public static string Launcherurl = null;
13 | public static string RedirectUrl = "";
14 | public static string AntiCheatUrl = "";
15 | public static string ExitSplashScreen = "";
16 | public static string ExitSettingsJson = "";
17 | public static string APIversion = null;
18 | public static string UserName = null;
19 | public static string FortnitePath = null;
20 | public static string Email = null;
21 | public static string Password = null;
22 | public static bool EOR = false;
23 | public static bool DiscordPRC = true;
24 | public static bool LoggedOut = false;
25 | public static bool RefreshToken = false;
26 | public static bool ForceClose = false;
27 | public static bool outdated = false;
28 | public static bool FinishedAPIRequest = false;
29 | public static bool BindPlayButton = true;
30 | public static bool ConnectionFailedToAPI = false;
31 |
32 | // options
33 | public static bool limitguestfeatures = true; // set to false to enable all features for guests.
34 | public static bool AllowLaunchingAnyVersion = true; // false is limited to 14.60 if set to true it will allow launching any version 12.41 is the highest version tested.
35 |
36 | //secrets
37 | public static string accessToken = "31811a3e1afdb125efa4151438f29928a5dcf6b403c13f0a2dde440bca545654";
38 | }
39 |
--------------------------------------------------------------------------------
/Dialogs/DownloadDialog.xaml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/Dialogs/DownloadDialog.xaml.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.UI.Xaml;
2 | using Microsoft.UI.Xaml.Controls;
3 | using Microsoft.UI.Xaml.Controls.Primitives;
4 | using Microsoft.UI.Xaml.Data;
5 | using Microsoft.UI.Xaml.Input;
6 | using Microsoft.UI.Xaml.Media;
7 | using Microsoft.UI.Xaml.Navigation;
8 | using System;
9 | using System.Collections.Generic;
10 | using System.IO;
11 | using System.IO.Compression;
12 | using System.Linq;
13 | using System.Net;
14 | using System.Runtime.InteropServices.WindowsRuntime;
15 | using Windows.Foundation;
16 | using Windows.Foundation.Collections;
17 | using Windows.Storage.Pickers;
18 | using Windows.Storage;
19 | using FortniteLauncher.Core;
20 | using FortniteLauncher.Helpers;
21 | using FortniteLauncher.Interop;
22 |
23 | // To learn more about WinUI, the WinUI project structure,
24 | // and more about our project templates, see: http://aka.ms/winui-project-info.
25 |
26 | namespace FortniteLauncher.Dialogs
27 | {
28 | ///
29 | /// An empty page that can be used on its own or navigated to within a Frame.
30 | ///
31 | public sealed partial class DownloadDialog : Page
32 | {
33 | int _downloadPrecentageProgress;
34 |
35 | ContentDialog _presenterContentDialog;
36 | string _downloadPathFull;
37 | string _downloadPath;
38 | DateTime lastUpdate;
39 | long lastBytes = 0;
40 |
41 | public DownloadDialog(ContentDialog PresenterDialog)
42 | {
43 | this.InitializeComponent();
44 |
45 | _presenterContentDialog = PresenterDialog;
46 |
47 | PresenterDialog.CloseButtonText = "Cancel";
48 | PresenterDialog.CloseButtonClick += PresenterDialog_CloseButtonClick;
49 | }
50 |
51 | private void PresenterDialog_CloseButtonClick(ContentDialog sender, ContentDialogButtonClickEventArgs args)
52 | {
53 |
54 | }
55 |
56 | private async void Page_Loaded(object sender, RoutedEventArgs e)
57 | {
58 | try
59 | {
60 | WebClient wc = new WebClient();
61 |
62 | //get the path
63 | FolderPicker openPicker = new Windows.Storage.Pickers.FolderPicker();
64 |
65 | // Retrieve the window handle (HWND) of the current WinUI 3 window.
66 | var window = Globals.m_window;
67 | var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(window);
68 |
69 | // Initialize the folder picker with the window handle (HWND).
70 | WinRT.Interop.InitializeWithWindow.Initialize(openPicker, hWnd);
71 |
72 | // Set options for your file picker
73 | openPicker.ViewMode = PickerViewMode.Thumbnail;
74 | openPicker.FileTypeFilter.Add("*");
75 |
76 | // Open the picker for the user to pick a file
77 | StorageFolder folder = await openPicker.PickSingleFolderAsync();
78 |
79 | if (folder == null)
80 | {
81 | _presenterContentDialog.Hide();
82 | return;
83 | }
84 |
85 | string path = folder.Path;
86 | _downloadPathFull = path + "\\8.20.zip";
87 |
88 | //does this actually improve download speed?
89 | //System.Net.ServicePointManager.DefaultConnectionLimit =
90 |
91 | DownloadState.Text = "Downloading";
92 |
93 | wc.DownloadProgressChanged += Wc_DownloadProgressChanged;
94 | wc.DownloadFileCompleted += Wc_DownloadFileCompleted;
95 | wc.DownloadFileAsync(new Uri("https://cdn.fnbuilds.services/14.60.rar"), _downloadPathFull);
96 | }
97 | catch (Exception ex)
98 | {
99 | MessageBox.Show(ex.Message, "An Error Occured");
100 | throw;
101 | }
102 | }
103 |
104 | private void Wc_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
105 | {
106 | DownloadProgress.IsIndeterminate = true;
107 | DownloadState.Text = "Extracting";
108 | ZipFile.ExtractToDirectory(_downloadPathFull, _downloadPath);
109 |
110 | DownloadState.Text = "Cleaning Up";
111 | File.Delete(_downloadPathFull);
112 |
113 | try
114 | {
115 | Definitions.FortnitePath = Globals.m_config.FortnitePath;
116 | Globals.m_config.FortnitePath = _downloadPath;
117 |
118 | Settings.SaveSettings();
119 | }
120 | catch (Exception ex)
121 | {
122 | MessageBox.Show(ex.Message, "An Error Occurred");
123 | throw;
124 | }
125 | }
126 |
127 | private void Wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
128 | {
129 | try
130 | {
131 | DownloadProgress.IsIndeterminate = false;
132 | DownloadProgress.Value = e.ProgressPercentage;
133 | DownloadProgressValue.Text = e.ProgressPercentage.ToString() + "%";
134 |
135 | _presenterContentDialog.Title = (Helpers.StorageSizesConverter.BytesToGigabytes(e.BytesReceived).ToString() + "GB / " + Helpers.StorageSizesConverter.BytesToGigabytes(e.TotalBytesToReceive).ToString() + "GB");
136 |
137 | if (lastBytes == 0)
138 | {
139 | lastUpdate = DateTime.Now;
140 | lastBytes = e.BytesReceived;
141 | return;
142 | }
143 |
144 | var now = DateTime.Now;
145 | var timeSpan = now - lastUpdate;
146 | var bytesChange = e.BytesReceived - lastBytes;
147 | var bytesPerSecond = bytesChange / timeSpan.Seconds;
148 |
149 | lastBytes = e.BytesReceived;
150 | lastUpdate = now;
151 |
152 | SpeedBox.Text = (StorageSizesConverter.BytesToMegabytes(bytesPerSecond).ToString()) + " MB/s";
153 | } catch
154 | {
155 | // fix crash??
156 | }
157 | }
158 | }
159 | }
160 |
--------------------------------------------------------------------------------
/ExitLauncher.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | WinExe
4 | net6.0-windows10.0.19041.0
5 | 10.0.17763.0
6 | Exit
7 | app.manifest
8 | x86;x64;ARM64
9 | win10-x86;win10-x64;win10-arm64
10 | win10-$(Platform).pubxml
11 | true
12 | true
13 | true
14 | None
15 | tiltedlogo.png
16 | Assets\ACTUALL ICON.ico
17 | FortniteLauncher.Program
18 | Exit
19 | False
20 |
21 | Exit
22 | Exit
23 | Rio
24 | Rio
25 | 1.0.0
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
75 |
76 |
77 |
78 |
79 |
80 | Always
81 |
82 |
83 | Always
84 |
85 |
86 | PreserveNewest
87 |
88 |
89 | Always
90 |
91 |
92 | Always
93 |
94 |
95 | Always
96 |
97 |
98 | Always
99 |
100 |
101 | Always
102 |
103 |
104 | Always
105 |
106 |
107 | Always
108 |
109 |
110 | Always
111 |
112 |
113 | Always
114 |
115 |
116 |
117 |
118 | True
119 | \
120 |
121 |
122 | True
123 | \
124 |
125 |
126 | MSBuild:Compile
127 |
128 |
129 |
130 |
131 | MSBuild:Compile
132 |
133 |
134 |
135 |
136 | MSBuild:Compile
137 |
138 |
139 |
140 |
141 | MSBuild:Compile
142 |
143 |
144 |
145 |
146 | MSBuild:Compile
147 |
148 |
149 |
150 |
151 | MSBuild:Compile
152 |
153 |
154 |
155 |
156 | MSBuild:Compile
157 |
158 |
159 |
160 |
165 |
166 | true
167 |
168 |
169 |
--------------------------------------------------------------------------------
/ExitLauncher.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.0.31903.59
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExitLauncher", "ExitLauncher.csproj", "{85D05C8E-92A9-407E-94AC-F0FB640DE707}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Debug|ARM64 = Debug|ARM64
12 | Debug|x64 = Debug|x64
13 | Debug|x86 = Debug|x86
14 | Release|Any CPU = Release|Any CPU
15 | Release|ARM64 = Release|ARM64
16 | Release|x64 = Release|x64
17 | Release|x86 = Release|x86
18 | EndGlobalSection
19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
20 | {85D05C8E-92A9-407E-94AC-F0FB640DE707}.Debug|Any CPU.ActiveCfg = Debug|x64
21 | {85D05C8E-92A9-407E-94AC-F0FB640DE707}.Debug|Any CPU.Build.0 = Debug|x64
22 | {85D05C8E-92A9-407E-94AC-F0FB640DE707}.Debug|Any CPU.Deploy.0 = Debug|x64
23 | {85D05C8E-92A9-407E-94AC-F0FB640DE707}.Debug|ARM64.ActiveCfg = Debug|ARM64
24 | {85D05C8E-92A9-407E-94AC-F0FB640DE707}.Debug|ARM64.Build.0 = Debug|ARM64
25 | {85D05C8E-92A9-407E-94AC-F0FB640DE707}.Debug|ARM64.Deploy.0 = Debug|ARM64
26 | {85D05C8E-92A9-407E-94AC-F0FB640DE707}.Debug|x64.ActiveCfg = Debug|x64
27 | {85D05C8E-92A9-407E-94AC-F0FB640DE707}.Debug|x64.Build.0 = Debug|x64
28 | {85D05C8E-92A9-407E-94AC-F0FB640DE707}.Debug|x64.Deploy.0 = Debug|x64
29 | {85D05C8E-92A9-407E-94AC-F0FB640DE707}.Debug|x86.ActiveCfg = Debug|x86
30 | {85D05C8E-92A9-407E-94AC-F0FB640DE707}.Debug|x86.Build.0 = Debug|x86
31 | {85D05C8E-92A9-407E-94AC-F0FB640DE707}.Debug|x86.Deploy.0 = Debug|x86
32 | {85D05C8E-92A9-407E-94AC-F0FB640DE707}.Release|Any CPU.ActiveCfg = Release|x64
33 | {85D05C8E-92A9-407E-94AC-F0FB640DE707}.Release|Any CPU.Build.0 = Release|x64
34 | {85D05C8E-92A9-407E-94AC-F0FB640DE707}.Release|Any CPU.Deploy.0 = Release|x64
35 | {85D05C8E-92A9-407E-94AC-F0FB640DE707}.Release|ARM64.ActiveCfg = Release|ARM64
36 | {85D05C8E-92A9-407E-94AC-F0FB640DE707}.Release|ARM64.Build.0 = Release|ARM64
37 | {85D05C8E-92A9-407E-94AC-F0FB640DE707}.Release|ARM64.Deploy.0 = Release|ARM64
38 | {85D05C8E-92A9-407E-94AC-F0FB640DE707}.Release|x64.ActiveCfg = Release|x64
39 | {85D05C8E-92A9-407E-94AC-F0FB640DE707}.Release|x64.Build.0 = Release|x64
40 | {85D05C8E-92A9-407E-94AC-F0FB640DE707}.Release|x64.Deploy.0 = Release|x64
41 | {85D05C8E-92A9-407E-94AC-F0FB640DE707}.Release|x86.ActiveCfg = Release|x86
42 | {85D05C8E-92A9-407E-94AC-F0FB640DE707}.Release|x86.Build.0 = Release|x86
43 | {85D05C8E-92A9-407E-94AC-F0FB640DE707}.Release|x86.Deploy.0 = Release|x86
44 | EndGlobalSection
45 | GlobalSection(SolutionProperties) = preSolution
46 | HideSolutionNode = FALSE
47 | EndGlobalSection
48 | EndGlobal
49 |
--------------------------------------------------------------------------------
/Globals.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.UI.Xaml;
2 | using Microsoft.UI.Xaml.Controls;
3 | using FortniteLauncher.Pages;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 |
10 | namespace FortniteLauncher
11 | {
12 | public class Globals
13 | {
14 | public static Window m_window;
15 |
16 | public static Config m_config;
17 |
18 | public static string Version = Definitions.CurrentVersion;
19 |
20 | public static void ChangePaneToggleBtnVisibility(bool IsVisible)
21 | {
22 | Button TitleBarPaneToggleBtn = MainWindow.TitleBarPaneToggleButton;
23 |
24 | if (IsVisible)
25 | {
26 | TitleBarPaneToggleBtn.Visibility = Visibility.Visible;
27 | }
28 | else
29 | {
30 | TitleBarPaneToggleBtn.Visibility = Visibility.Collapsed;
31 | }
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/Helpers/PathHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 |
4 | namespace FortniteLauncher.Helpers
5 | {
6 | public class PathHelper
7 | {
8 | public static bool IsPathValid(string path)
9 | {
10 | string enginePath = Path.Combine(path, "Engine");
11 | string fortniteGamePath = Path.Combine(path, "FortniteGame");
12 |
13 | bool engineDirectoryExists = Directory.Exists(enginePath);
14 | bool fortniteGameDirectoryExists = Directory.Exists(fortniteGamePath);
15 |
16 | if (!engineDirectoryExists || !fortniteGameDirectoryExists)
17 | {
18 | return false;
19 | }
20 |
21 | string parentDirectory = Path.GetDirectoryName(path);
22 | bool parentDirectoryExists = !string.IsNullOrEmpty(parentDirectory) && Directory.Exists(parentDirectory);
23 |
24 | return parentDirectoryExists;
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Helpers/StorageSizesConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace FortniteLauncher.Helpers
8 | {
9 | internal class StorageSizesConverter
10 | {
11 | public static double BytesToGigabytes(long bytes)
12 | {
13 | return Math.Round((double)bytes / (1024 * 1024 * 1024), 2);
14 | }
15 | public static double BytesToMegabytes(long bytes)
16 | {
17 | return Math.Round((double)bytes / (1024 * 1024), 2);
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Interop/MessageBox.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Runtime.InteropServices;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace FortniteLauncher.Interop
9 | {
10 | internal class MessageBox
11 | {
12 | public enum Options
13 | {
14 | OK
15 | }
16 | public static void Show(string Content, string Title = null, Options Options = Options.OK)
17 | {
18 | [DllImport("user32.dll")]
19 | static extern int MessageBox(IntPtr hWind, String text, String caption, int options);
20 | MessageBox(IntPtr.Zero, Content, Title, Convert.ToInt32(Options));
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/MainWindow.xaml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
32 |
37 |
38 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/MainWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.UI.Xaml;
2 | using Microsoft.UI.Xaml.Controls;
3 | using Microsoft.UI.Xaml.Media;
4 | using Microsoft.UI.Xaml.Navigation;
5 | using FortniteLauncher.Pages;
6 | using System;
7 | using System.ComponentModel;
8 | using WinUIEx;
9 |
10 | // To learn more about WinUI, the WinUI project structure,
11 | // and more about our project templates, see: http://aka.ms/winui-project-info.
12 |
13 | namespace FortniteLauncher
14 | {
15 | ///
16 | /// An empty window that can be used on its own or navigated to within a Frame.
17 | ///
18 | public sealed partial class MainWindow : WinUIEx.WindowEx
19 | {
20 | public static Frame ShellFrame { get; private set; }
21 | public static Button TitleBarPaneToggleButton { get; private set; }
22 | public MainWindow()
23 | {
24 | this.InitializeComponent();
25 | this.ExtendsContentIntoTitleBar = true;
26 | this.SetTitleBar(AppTitleBar);
27 |
28 | this.SetWindowSize(1200, 725);
29 | this.CenterOnScreen();
30 | this.SetIsResizable(false);
31 |
32 | //this might be a bug, but trying to disable maximize makes it even worse
33 | //this.SetIsMaximizable(false);
34 |
35 | this.Title = "Exit Launcher";
36 |
37 | MicaBackdrop backdrop = new MicaBackdrop();
38 | backdrop.Kind = Microsoft.UI.Composition.SystemBackdrops.MicaKind.Base;
39 | this.SystemBackdrop = backdrop;
40 |
41 | ShellFrame = MainWindowFrame;
42 | TitleBarPaneToggleButton = PaneToggleBtn;
43 |
44 | MainWindowFrame.Navigate(typeof(LoginPage));
45 |
46 | this.SetIcon("Assets\\ACTUALL ICON.ico");
47 | }
48 | private void PaneToggleBtn_Click(object sender, RoutedEventArgs e)
49 | {
50 | try
51 | {
52 | if (MainShellPage.STATIC_MainNavigation.IsPaneOpen)
53 | {
54 |
55 | MainShellPage.STATIC_MainNavigation.IsPaneOpen = false;
56 | }
57 | else
58 | {
59 |
60 | MainShellPage.STATIC_MainNavigation.IsPaneOpen = true;
61 | }
62 | } catch
63 | {
64 | // no.
65 | }
66 | }
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/Package.appxmanifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
14 |
15 |
16 |
17 |
18 | ExitLauncher
19 | jurij
20 | Assets\StoreLogo.png
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
36 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/Pages/DownloadsPage.xaml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
28 |
29 |
30 |
31 |
32 |
33 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/Pages/DownloadsPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.UI.Xaml;
2 | using Microsoft.UI.Xaml.Controls;
3 | using Microsoft.UI.Xaml.Controls.Primitives;
4 | using Microsoft.UI.Xaml.Data;
5 | using Microsoft.UI.Xaml.Input;
6 | using Microsoft.UI.Xaml.Media;
7 | using Microsoft.UI.Xaml.Media.Animation;
8 | using Microsoft.UI.Xaml.Navigation;
9 | using FortniteLauncher.Core;
10 | using FortniteLauncher.Helpers;
11 | using FortniteLauncher.Services;
12 | using SharpCompress.Common;
13 | using SharpCompress.Readers;
14 | using System;
15 | using System.IO;
16 | using System.IO.Compression;
17 | using System.Net;
18 | using System.Threading.Tasks;
19 | using Windows.Storage;
20 | using Windows.Storage.Pickers;
21 |
22 | namespace FortniteLauncher.Pages
23 | {
24 | public sealed partial class DownloadsPage : Page
25 | {
26 | private string _buildPath = string.Empty;
27 | private string _downloadPathFull;
28 | private DateTime _lastUpdate;
29 | private long _lastBytes = 0;
30 | private WebClient _webClient;
31 | private string _downloadPath;
32 | int _downloadPrecentageProgress;
33 | public DownloadsPage()
34 | {
35 | this.InitializeComponent();
36 | InitializeBuildPath();
37 | }
38 |
39 | private void InitializeBuildPath()
40 | {
41 | if (Globals.m_config.FortnitePath == null || !PathHelper.IsPathValid(Globals.m_config.FortnitePath))
42 | {
43 | _buildPath = "Path must contain FortniteGame and Engine folders!";
44 | }
45 | else
46 | {
47 | Definitions.FortnitePath = Globals.m_config.FortnitePath;
48 | _buildPath = Globals.m_config.FortnitePath;
49 | }
50 | }
51 | public static bool IsFileLocked(string filePath)
52 | {
53 | try
54 | {
55 | using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.None))
56 | {
57 | // If the file can be opened with no sharing, it's not locked
58 | }
59 | }
60 | catch (IOException)
61 | {
62 | // The file is locked
63 | return true;
64 | }
65 |
66 | // The file is not locked
67 | return false;
68 | }
69 | public static async Task WaitForFileToBeReleased(string filePath)
70 | {
71 | while (IsFileLocked(filePath))
72 | {
73 | await Task.Delay(100); // Delay to avoid busy-waiting
74 | }
75 | }
76 | private async void ChangeInstallPath_Click(object sender, RoutedEventArgs e)
77 | {
78 | try
79 | {
80 | FolderPicker openPicker = CreateFolderPicker();
81 | StorageFolder folder = await openPicker.PickSingleFolderAsync();
82 |
83 | if (folder != null && PathHelper.IsPathValid(folder.Path))
84 | {
85 | Definitions.FortnitePath = Globals.m_config.FortnitePath;
86 | Globals.m_config.FortnitePath = folder.Path;
87 | _buildPath = folder.Path;
88 |
89 | Settings.SaveSettings();
90 |
91 | // Refresh the page
92 | Frame.Navigate(typeof(DownloadsPage), "Downloads");
93 | }
94 | else
95 | {
96 | DialogService.ShowSimpleDialog("The selected path is invalid.", "Path Invalid");
97 | }
98 | }
99 | catch (Exception ex)
100 | {
101 | DialogService.ShowSimpleDialog("Unknown error: " + ex.Message, "Error");
102 | }
103 | }
104 |
105 | private FolderPicker CreateFolderPicker()
106 | {
107 | FolderPicker openPicker = new Windows.Storage.Pickers.FolderPicker();
108 | var hWnd = WinRT.Interop.WindowNative.GetWindowHandle(Globals.m_window);
109 | WinRT.Interop.InitializeWithWindow.Initialize(openPicker, hWnd);
110 | openPicker.ViewMode = PickerViewMode.Thumbnail;
111 | openPicker.FileTypeFilter.Add("*");
112 | return openPicker;
113 | }
114 |
115 | public async void DownloadBuild_Click(object sender, RoutedEventArgs e)
116 | {
117 | try
118 | {
119 | if (DownloadBuild.Content == "Cancel")
120 | {
121 | _webClient?.CancelAsync();
122 | if (_webClient != null)
123 | {
124 | _webClient.DownloadProgressChanged -= Wc_DownloadProgressChanged;
125 | _webClient.DownloadFileCompleted -= Wc_DownloadFileCompleted;
126 | _webClient.Dispose();
127 | }
128 | await Task.Delay(5000);
129 | if (File.Exists(_downloadPathFull))
130 | {
131 | _webClient = null;
132 | try
133 | {
134 | File.Delete(_downloadPathFull);
135 | Frame.Navigate(typeof(DownloadsPage), "Downloads");
136 | }
137 | catch (Exception ex)
138 | {
139 | DialogService.ShowSimpleDialog("Failed to download 14.60 build: " + ex.Message, "Error");
140 | }
141 | }
142 |
143 | DownloadInProgressInfoBar.IsOpen = false;
144 | DownloadBuild.Content = "Download";
145 | return;
146 | }
147 |
148 | _webClient = new WebClient();
149 |
150 | FolderPicker openPicker = CreateFolderPicker();
151 | StorageFolder folder = await openPicker.PickSingleFolderAsync();
152 |
153 | if (folder != null)
154 | {
155 | long requiredSpace = GetRequiredSpace();
156 | long availableSpace = CheckDiskSpace(folder.Path);
157 |
158 | if (availableSpace >= requiredSpace)
159 | {
160 | string path = folder.Path;
161 | _downloadPathFull = Path.Combine(path, "14.60.rar");
162 | _downloadPath = path;
163 | _webClient.DownloadProgressChanged += Wc_DownloadProgressChanged;
164 | _webClient.DownloadFileCompleted += Wc_DownloadFileCompleted;
165 | _webClient.DownloadFileAsync(new Uri("https://cdn.fnbuilds.services/14.60.rar"), _downloadPathFull);
166 |
167 | DownloadInProgressInfoBar.IsOpen = true;
168 | DownloadBuild.Content = "Cancel";
169 | }
170 | else
171 | {
172 | DialogService.ShowSimpleDialog("Not enough disk space available for the download.", "Disk Space Error");
173 | }
174 | }
175 | }
176 | catch (Exception ex)
177 | {
178 | DialogService.ShowSimpleDialog("Failed to download 14.60 build: " + ex.Message, "Error");
179 | }
180 | }
181 |
182 | private long GetRequiredSpace()
183 | {
184 | return 46900000000; // Adjust this value as needed
185 | }
186 |
187 | private long CheckDiskSpace(string folderPath)
188 | {
189 | DriveInfo driveInfo = new DriveInfo(new DirectoryInfo(folderPath).Root.FullName);
190 | return driveInfo.AvailableFreeSpace;
191 | }
192 |
193 | private async void Wc_DownloadFileCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
194 | {
195 | try
196 | {
197 | await WaitForFileToBeReleased(_downloadPathFull);
198 | DownloadProgress.IsIndeterminate = true;
199 | using (Stream stream = File.OpenRead(_downloadPathFull))
200 | {
201 | using (var reader = ReaderFactory.Open(stream))
202 | {
203 | while (reader.MoveToNextEntry())
204 | {
205 | if (!reader.Entry.IsDirectory)
206 | {
207 | reader.WriteEntryToDirectory(_downloadPath, new ExtractionOptions()
208 | {
209 | ExtractFullPath = true,
210 | Overwrite = true
211 | });
212 | }
213 | }
214 | }
215 | }
216 |
217 |
218 | File.Delete(_downloadPathFull);
219 | Definitions.FortnitePath = Globals.m_config.FortnitePath;
220 | Globals.m_config.FortnitePath = _downloadPath;
221 | Settings.SaveSettings();
222 | Frame.Navigate(typeof(DownloadsPage), "Downloads");
223 | }
224 | catch (Exception ex)
225 | {
226 | DialogService.ShowSimpleDialog(ex.Message, "An Error Occurred");
227 | }
228 |
229 | DownloadInProgressInfoBar.IsOpen = false;
230 | DownloadBuild.Content = "Download";
231 | }
232 |
233 | private async void Wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
234 | {
235 | try
236 | {
237 | _downloadPrecentageProgress = e.ProgressPercentage; // Update the progress
238 | DownloadProgress.IsIndeterminate = false;
239 | DownloadProgress.Value = _downloadPrecentageProgress;
240 | DownloadProgressValue.Text = _downloadPrecentageProgress.ToString() + "%";
241 |
242 | DownloadedGB.Text = $"{StorageSizesConverter.BytesToGigabytes(e.BytesReceived)} GB / 0 GB"; // we really dont know the actual size so lets leave it null
243 |
244 | if (_lastBytes == 0)
245 | {
246 | _lastUpdate = DateTime.Now;
247 | _lastBytes = e.BytesReceived;
248 | return;
249 | }
250 |
251 | var now = DateTime.Now;
252 | var timeSpan = now - _lastUpdate;
253 |
254 | // Check if timeSpan.Seconds is zero to avoid division by zero
255 | var bytesChange = e.BytesReceived - _lastBytes;
256 | var bytesPerSecond = timeSpan.Seconds != 0 ? bytesChange / timeSpan.Seconds : 0;
257 |
258 | _lastBytes = e.BytesReceived;
259 | _lastUpdate = now;
260 | if (bytesPerSecond == 0)
261 | {
262 | // idk maybe recheck?
263 | SpeedBox.Text = $"ERROR MB/s";
264 | }
265 | SpeedBox.Text = $"{StorageSizesConverter.BytesToMegabytes(bytesPerSecond)} MB/s";
266 | }
267 | catch (Exception ex)
268 | {
269 | DialogService.ShowSimpleDialog("Failed to download 14.60 build: " + ex.Message, "Error");
270 | }
271 | }
272 | }
273 | }
274 |
--------------------------------------------------------------------------------
/Pages/HomePage.xaml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
50 |
51 |
52 |
53 |
54 |
57 |
58 |
59 |
60 |
61 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
--------------------------------------------------------------------------------
/Pages/HomePage.xaml.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.UI.Xaml;
2 | using Microsoft.UI.Xaml.Controls;
3 | using Microsoft.UI.Xaml.Controls.Primitives;
4 | using Microsoft.UI.Xaml.Data;
5 | using Microsoft.UI.Xaml.Input;
6 | using Microsoft.UI.Xaml.Media;
7 | using Microsoft.UI.Xaml.Navigation;
8 | using System;
9 | using System.Collections.Generic;
10 | using System.IO;
11 | using System.Linq;
12 | using System.Runtime.InteropServices.WindowsRuntime;
13 | using Windows.Foundation;
14 | using Windows.Foundation.Collections;
15 |
16 | // To learn more about WinUI, the WinUI project structure,
17 | // and more about our project templates, see: http://aka.ms/winui-project-info.
18 |
19 | namespace FortniteLauncher.Pages
20 | {
21 | ///
22 | /// An empty page that can be used on its own or navigated to within a Frame.
23 | ///
24 | public sealed partial class HomePage : Page
25 | {
26 | public HomePage()
27 | {
28 | this.InitializeComponent();
29 | }
30 |
31 | private void PlayNow_Click(object sender, RoutedEventArgs e)
32 | {
33 |
34 | }
35 |
36 | private void LogoutBtn_Click(object sender, RoutedEventArgs e)
37 | {
38 | //process logout, clear variables
39 | MainWindow.ShellFrame.Navigate(typeof(LoginPage));
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/Pages/ItemShopPage.xaml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/Pages/ItemShopPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.UI.Xaml;
2 | using Microsoft.UI.Xaml.Controls;
3 | using Microsoft.UI.Xaml.Controls.Primitives;
4 | using Microsoft.UI.Xaml.Data;
5 | using Microsoft.UI.Xaml.Input;
6 | using Microsoft.UI.Xaml.Media;
7 | using Microsoft.UI.Xaml.Navigation;
8 | using System;
9 | using System.Collections.Generic;
10 | using System.IO;
11 | using System.Linq;
12 | using System.Runtime.InteropServices.WindowsRuntime;
13 | using Windows.Foundation;
14 | using Windows.Foundation.Collections;
15 |
16 | // To learn more about WinUI, the WinUI project structure,
17 | // and more about our project templates, see: http://aka.ms/winui-project-info.
18 |
19 | namespace FortniteLauncher.Pages
20 | {
21 | ///
22 | /// An empty page that can be used on its own or navigated to within a Frame.
23 | ///
24 | public sealed partial class ItemShopPage : Page
25 | {
26 | public ItemShopPage()
27 | {
28 | this.InitializeComponent();
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Pages/LoginPage.xaml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/Pages/LoginPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using DnsClient;
2 | using Microsoft.UI.Text;
3 | using Microsoft.UI.Xaml;
4 | using Microsoft.UI.Xaml.Controls;
5 | using Microsoft.UI.Xaml.Controls.Primitives;
6 | using Microsoft.UI.Xaml.Data;
7 | using Microsoft.UI.Xaml.Input;
8 | using Microsoft.UI.Xaml.Media;
9 | using Microsoft.UI.Xaml.Media.Animation;
10 | using Microsoft.UI.Xaml.Media.Imaging;
11 | using Microsoft.UI.Xaml.Navigation;
12 | using FortniteLauncher.Core;
13 | using FortniteLauncher.Interop;
14 | using FortniteLauncher.MongoDB;
15 | using FortniteLauncher.Services;
16 | using System;
17 | using System.Collections.Generic;
18 | using System.IO;
19 | using System.Linq;
20 | using System.Net;
21 | using System.Runtime.InteropServices.WindowsRuntime;
22 | using System.Security.Cryptography;
23 | using System.Threading;
24 | using System.Threading.Tasks;
25 | using Windows.ApplicationModel.Search.Core;
26 | using Windows.Foundation;
27 | using Windows.Foundation.Collections;
28 |
29 |
30 | // To learn more about WinUI, the WinUI project structure,
31 | // and more about our project templates, see: http://aka.ms/winui-project-info.
32 |
33 | namespace FortniteLauncher.Pages
34 | {
35 | ///
36 | /// An empty page that can be used on its own or navigated to within a Frame.
37 | ///
38 | public sealed partial class LoginPage : Page
39 | {
40 | public static string RootDirectory = Definitions.RootDirectory;
41 | public LoginPage()
42 | {
43 | this.InitializeComponent();
44 | Globals.ChangePaneToggleBtnVisibility(false);
45 | }
46 | private async void LoginBtn_Click(object sender, RoutedEventArgs e)
47 | {
48 | await loginAsync(sender, e);
49 | }
50 |
51 | public async Task loginAsync(object sender, RoutedEventArgs e)
52 | {
53 | if (string.IsNullOrEmpty(MailBox.Text) || string.IsNullOrWhiteSpace(MailBox.Text) || string.IsNullOrEmpty(PasswordBox.Password) || string.IsNullOrWhiteSpace(PasswordBox.Password))
54 | {
55 | //this is a terrible way of doing it, but it works
56 | StackPanel panel = new StackPanel();
57 | panel.Spacing = 2;
58 |
59 | TextBlock title = new TextBlock();
60 | title.Text = "Access Denied";
61 | title.FontWeight = FontWeights.Medium;
62 |
63 | TextBlock desc = new TextBlock();
64 | desc.Text = "Email/Password is required.";
65 |
66 | panel.Children.Add(title);
67 | panel.Children.Add(desc);
68 |
69 | Grid g = new Grid();
70 | ColumnDefinition def1 = new ColumnDefinition();
71 | ColumnDefinition def2 = new ColumnDefinition();
72 | def1.Width = GridLength.Auto;
73 | def2.Width = GridLength.Auto;
74 | g.ColumnDefinitions.Add(def1);
75 | g.ColumnDefinitions.Add(def2);
76 |
77 | FontIcon icon = new FontIcon();
78 | icon.VerticalAlignment = VerticalAlignment.Center;
79 | icon.Glyph = "\uE72E";
80 | icon.FontSize = 28;
81 | icon.Margin = new Thickness(0, 0, 12, 0);
82 |
83 | g.Children.Add(icon);
84 | g.Children.Add(panel);
85 |
86 | Grid.SetColumn(icon, 0);
87 | Grid.SetColumn(panel, 1);
88 |
89 | ErrorNotification.Show(g, 2500);
90 | }
91 | else
92 | {
93 | Settings.SaveSettings();
94 | LoginBtn.IsEnabled = false;
95 | ProgressRing loading = new ProgressRing();
96 | loading.IsIndeterminate = true;
97 | loading.Foreground = new SolidColorBrush(Microsoft.UI.Colors.Black);
98 | loading.HorizontalAlignment = HorizontalAlignment.Center;
99 | LoginBtn.Content = loading;
100 | string Login = await MongoDBAuthenticator.CheckLogin(MailBox.Text, PasswordBox.Password);
101 | if (Login == "Invalid")
102 | {
103 | ShowPasswordIncorrectError();
104 | ((Button)sender).IsEnabled = true;
105 | LoginBtn.Content = "Login";
106 |
107 | } else if (Login == "Deny")
108 | {
109 | ToManyReports();
110 | ((Button)sender).IsEnabled = true;
111 | LoginBtn.Content = "Login";
112 | }
113 | else if (Login == "Error")
114 | {
115 | ConnectionFailure();
116 | ((Button)sender).IsEnabled = true;
117 | LoginBtn.Content = "Login";
118 | }
119 | else if (Login == "Banned")
120 | {
121 | UserBanned();
122 | ((Button)sender).IsEnabled = true;
123 | LoginBtn.Content = "Login";
124 | }
125 | else if (Login == "Success")
126 | {
127 | if (Convert.ToBoolean(RememberMeCheckBox.IsChecked))
128 | {
129 | Globals.m_config.Email = MailBox.Text;
130 | Globals.m_config.Password = PasswordBox.Password; // fixed the save settings here
131 |
132 | Settings.SaveSettings();
133 | }
134 | await CheckForUpdatesAPI.Start();
135 | MainWindow.ShellFrame.Navigate(typeof(MainShellPage), null, new DrillInNavigationTransitionInfo());
136 | }
137 | else
138 | {
139 | ConnectionFailure();
140 | ((Button)sender).IsEnabled = true;
141 | LoginBtn.Content = "Login";
142 | }
143 | }
144 | }
145 |
146 | #region Errors
147 | public void ShowPasswordIncorrectError()
148 | {
149 | //this is a terrible way of doing it, but it works
150 | StackPanel panel = new StackPanel();
151 | panel.Spacing = 2;
152 |
153 | TextBlock title = new TextBlock();
154 | title.Text = "Access Denied";
155 | title.FontWeight = FontWeights.Medium;
156 |
157 | TextBlock desc = new TextBlock();
158 | desc.Text = "Your e-mail and/or password are incorrect. Please check them and try again.";
159 |
160 | panel.Children.Add(title);
161 | panel.Children.Add(desc);
162 |
163 | Grid g = new Grid();
164 | ColumnDefinition def1 = new ColumnDefinition();
165 | ColumnDefinition def2 = new ColumnDefinition();
166 | def1.Width = GridLength.Auto;
167 | def2.Width = GridLength.Auto;
168 | g.ColumnDefinitions.Add(def1);
169 | g.ColumnDefinitions.Add(def2);
170 |
171 | FontIcon icon = new FontIcon();
172 | icon.VerticalAlignment = VerticalAlignment.Center;
173 | icon.Glyph = "\uE72E";
174 | icon.FontSize = 28;
175 | icon.Margin = new Thickness(0, 0, 12, 0);
176 |
177 | g.Children.Add(icon);
178 | g.Children.Add(panel);
179 |
180 | Grid.SetColumn(icon, 0);
181 | Grid.SetColumn(panel, 1);
182 |
183 | ErrorNotification.Show(g, 2500);
184 | }
185 |
186 | public void UserBanned()
187 | {
188 | try // it crashes so lets put it in a try ig
189 | {
190 | //this is a terrible way of doing it, but it works
191 | StackPanel panel = new StackPanel();
192 | panel.Spacing = 2;
193 |
194 | TextBlock title = new TextBlock();
195 | title.Text = "Banned";
196 | title.FontWeight = FontWeights.Medium;
197 |
198 | TextBlock desc = new TextBlock();
199 | desc.Text = "Your account has been banned appeal at discord.gg/exitfn";
200 |
201 | panel.Children.Add(title);
202 | panel.Children.Add(desc);
203 |
204 | Grid g = new Grid();
205 | ColumnDefinition def1 = new ColumnDefinition();
206 | ColumnDefinition def2 = new ColumnDefinition();
207 | def1.Width = GridLength.Auto;
208 | def2.Width = GridLength.Auto;
209 | g.ColumnDefinitions.Add(def1);
210 | g.ColumnDefinitions.Add(def2);
211 |
212 | FontIcon icon = new FontIcon();
213 | icon.VerticalAlignment = VerticalAlignment.Center;
214 | icon.Glyph = "\uE72E";
215 | icon.FontSize = 28;
216 | icon.Margin = new Thickness(0, 0, 12, 0);
217 |
218 | g.Children.Add(icon);
219 | g.Children.Add(panel);
220 |
221 | Grid.SetColumn(icon, 0);
222 | Grid.SetColumn(panel, 1);
223 |
224 | ErrorNotification.Show(g, 2500);
225 | }
226 | catch
227 | {
228 | // ignore the error maybe?
229 | }
230 | }
231 |
232 | public void ConnectionFailure()
233 | {
234 | //this is a terrible way of doing it, but it works
235 | StackPanel panel = new StackPanel();
236 | panel.Spacing = 2;
237 |
238 | TextBlock title = new TextBlock();
239 | title.Text = "Connection Failed";
240 | title.FontWeight = FontWeights.Medium;
241 |
242 | TextBlock desc = new TextBlock();
243 | desc.Text = "Exit API is not responding please try again later.";
244 |
245 | panel.Children.Add(title);
246 | panel.Children.Add(desc);
247 |
248 | Grid g = new Grid();
249 | ColumnDefinition def1 = new ColumnDefinition();
250 | ColumnDefinition def2 = new ColumnDefinition();
251 | def1.Width = GridLength.Auto;
252 | def2.Width = GridLength.Auto;
253 | g.ColumnDefinitions.Add(def1);
254 | g.ColumnDefinitions.Add(def2);
255 |
256 | FontIcon icon = new FontIcon();
257 | icon.VerticalAlignment = VerticalAlignment.Center;
258 | icon.Glyph = "\uE72E";
259 | icon.FontSize = 28;
260 | icon.Margin = new Thickness(0, 0, 12, 0);
261 |
262 | g.Children.Add(icon);
263 | g.Children.Add(panel);
264 |
265 | Grid.SetColumn(icon, 0);
266 | Grid.SetColumn(panel, 1);
267 |
268 | ErrorNotification.Show(g, 2500);
269 | }
270 |
271 | public void ToManyReports()
272 | {
273 | //this is a terrible way of doing it, but it works
274 | StackPanel panel = new StackPanel();
275 | panel.Spacing = 2;
276 |
277 | TextBlock title = new TextBlock();
278 | title.Text = "Account Locked";
279 | title.FontWeight = FontWeights.Medium;
280 |
281 | TextBlock desc = new TextBlock();
282 | desc.Text = "Sorry your account has to many pending reports please contact the support team for further assistance.";
283 |
284 | panel.Children.Add(title);
285 | panel.Children.Add(desc);
286 |
287 | Grid g = new Grid();
288 | ColumnDefinition def1 = new ColumnDefinition();
289 | ColumnDefinition def2 = new ColumnDefinition();
290 | def1.Width = GridLength.Auto;
291 | def2.Width = GridLength.Auto;
292 | g.ColumnDefinitions.Add(def1);
293 | g.ColumnDefinitions.Add(def2);
294 |
295 | FontIcon icon = new FontIcon();
296 | icon.VerticalAlignment = VerticalAlignment.Center;
297 | icon.Glyph = "\uE72E";
298 | icon.FontSize = 28;
299 | icon.Margin = new Thickness(0, 0, 12, 0);
300 |
301 | g.Children.Add(icon);
302 | g.Children.Add(panel);
303 |
304 | Grid.SetColumn(icon, 0);
305 | Grid.SetColumn(panel, 1);
306 |
307 | ErrorNotification.Show(g, 2500);
308 | }
309 |
310 | #endregion
311 |
312 | private void BannerImg_Loaded(object sender, RoutedEventArgs e)
313 | {
314 | BannerImg.Source = new BitmapImage(new Uri("ms-appx:///Assets/Banner-dark.png"));
315 | }
316 | private async void Page_Loaded(object sender, RoutedEventArgs e)
317 | {
318 | //MainWindow.ShellFrame.Navigate(typeof(MainShellPage));
319 | try
320 | {
321 | if (Definitions.outdated == true && Definitions.limitguestfeatures == true)
322 | {
323 | LoginBtn.IsEnabled = false;
324 | guestlogin();
325 | } else
326 | if (Convert.ToBoolean(RememberMeCheckBox.IsChecked))
327 | {
328 | if (Definitions.LoggedOut == true)
329 | {
330 | MailBox.Text = Globals.m_config.Email;
331 | PasswordBox.Password = Globals.m_config.Password;
332 | }
333 | else if (Definitions.RefreshToken == true)
334 | {
335 | // not the best way to do it works
336 | MailBox.Text = Globals.m_config.Email;
337 | PasswordBox.Password = Globals.m_config.Password;
338 | LoginBtn.IsEnabled = false;
339 | ProgressRing loading = new ProgressRing();
340 | loading.IsIndeterminate = true;
341 | loading.Foreground = new SolidColorBrush(Microsoft.UI.Colors.Black);
342 | loading.HorizontalAlignment = HorizontalAlignment.Center;
343 | LoginBtn.Content = loading;
344 | await Task.Delay(2000);
345 | Definitions.LoggedOut = false;
346 | string Login = await MongoDBAuthenticator.CheckLogin(MailBox.Text, PasswordBox.Password);
347 | if (Login == "Invalid")
348 | {
349 | Definitions.LoggedOut = true;
350 | DialogService.ShowSimpleDialog("Failed to refresh Account Token.", "Error");
351 | ShowPasswordIncorrectError();
352 | ((Button)sender).IsEnabled = true;
353 | LoginBtn.Content = "Login";
354 |
355 | }
356 | else if (Login == "Deny")
357 | {
358 | ToManyReports();
359 | ((Button)sender).IsEnabled = true;
360 | LoginBtn.Content = "Login";
361 | }
362 | else if (Login == "Error")
363 | {
364 | Definitions.LoggedOut = true;
365 | DialogService.ShowSimpleDialog("Failed to refresh Account Token.", "Error");
366 | ConnectionFailure();
367 | ((Button)sender).IsEnabled = true;
368 | LoginBtn.Content = "Login";
369 | }
370 | else if (Login == "Banned")
371 | {
372 | Definitions.LoggedOut = true;
373 | DialogService.ShowSimpleDialog("Failed to refresh Account Token.", "Error");
374 | UserBanned();
375 | LoginBtn.IsEnabled = true;
376 | LoginBtn.Content = "Login";
377 | }
378 | else if (Login == "Success")
379 | {
380 | DialogService.ShowSimpleDialog("Launcher was successfully refreshed.", "Success");
381 | Definitions.RefreshToken = false;
382 | if (Convert.ToBoolean(RememberMeCheckBox.IsChecked))
383 | {
384 | Globals.m_config.Email = MailBox.Text;
385 | Globals.m_config.Password = PasswordBox.Password; // fixed the save settings here
386 |
387 | Settings.SaveSettings();
388 | }
389 | await CheckForUpdatesAPI.Start();
390 | MainWindow.ShellFrame.Navigate(typeof(MainShellPage));
391 | }
392 | else
393 | Definitions.LoggedOut = true;
394 | {
395 | DialogService.ShowSimpleDialog("Failed to refresh Account Token.", "Error");
396 | ConnectionFailure();
397 | LoginBtn.IsEnabled = true;
398 | LoginBtn.Content = "Login";
399 | }
400 | }
401 | else
402 | {
403 | if (Globals.m_config.Email != null && Globals.m_config.Password != null)
404 | {
405 | // not the best way to do it works
406 | MailBox.Text = Globals.m_config.Email;
407 | PasswordBox.Password = Globals.m_config.Password;
408 | LoginBtn.IsEnabled = false;
409 | ProgressRing loading = new ProgressRing();
410 | loading.IsIndeterminate = true;
411 | loading.Foreground = new SolidColorBrush(Microsoft.UI.Colors.Black);
412 | loading.HorizontalAlignment = HorizontalAlignment.Center;
413 | LoginBtn.Content = loading;
414 | await Task.Delay(2000);
415 | Definitions.LoggedOut = false;
416 | string Login = await MongoDBAuthenticator.CheckLogin(MailBox.Text, PasswordBox.Password);
417 | if (Login == "Invalid")
418 | {
419 | Definitions.LoggedOut = true;
420 | ShowPasswordIncorrectError();
421 | LoginBtn.IsEnabled = true;
422 | LoginBtn.Content = "Login";
423 |
424 | }
425 | else if (Login == "Deny")
426 | {
427 | ToManyReports();
428 | ((Button)sender).IsEnabled = true;
429 | LoginBtn.Content = "Login";
430 | }
431 | else if (Login == "Error")
432 | {
433 | Definitions.LoggedOut = true;
434 | ConnectionFailure();
435 | LoginBtn.IsEnabled = true;
436 | LoginBtn.Content = "Login";
437 | }
438 | else if (Login == "Banned")
439 | {
440 | Definitions.LoggedOut = true;
441 | UserBanned();
442 | LoginBtn.IsEnabled = true;
443 | LoginBtn.Content = "Login";
444 | }
445 | else if (Login == "Success")
446 | {
447 | string api = await API.Connect();
448 | while (api == null) { await Task.Delay(2000); }
449 | if (api == "Success")
450 | {
451 | if (Convert.ToBoolean(RememberMeCheckBox.IsChecked))
452 | {
453 | Globals.m_config.Email = MailBox.Text;
454 | Globals.m_config.Password = PasswordBox.Password; // fixed the save settings here
455 |
456 | Settings.SaveSettings();
457 | }
458 | await CheckForUpdatesAPI.Start();
459 | MainWindow.ShellFrame.Navigate(typeof(MainShellPage));
460 | } else
461 | {
462 | ConnectionFailure();
463 | }
464 | }
465 | else
466 | {
467 | Definitions.LoggedOut = true;
468 | ConnectionFailure();
469 | LoginBtn.IsEnabled = true;
470 | LoginBtn.Content = "Login";
471 | }
472 | }
473 | }
474 | }
475 | }
476 | catch
477 | {
478 | // ignore
479 | }
480 | }
481 |
482 | bool bypassWaitTime = false;
483 | private async void LoginGuestBtn_Click(object sender, RoutedEventArgs e)
484 | {
485 | guestlogin();
486 | }
487 | void guestlogin()
488 | {
489 | //just so i do not need to wait like 8 seconds while testing
490 | if (MailBox.Text == "CanBypassWaitTimes")
491 | {
492 | bypassWaitTime = true;
493 | }
494 |
495 | ProgressRing loading = new ProgressRing();
496 | loading.IsIndeterminate = true;
497 | loading.Foreground = new SolidColorBrush(Microsoft.UI.Colors.Black);
498 | loading.HorizontalAlignment = HorizontalAlignment.Center;
499 | LoginGuestBtn.Content = loading;
500 | Definitions.outdated = true;
501 | MainShellPage.DisplayUsername = "Guest";
502 |
503 | if (Convert.ToBoolean(RememberMeCheckBox.IsChecked))
504 | {
505 | Globals.m_config.Email = MailBox.Text;
506 | Globals.m_config.Password = PasswordBox.Password; // fixed the save settings here
507 |
508 | Settings.SaveSettings();
509 | }
510 |
511 | if (bypassWaitTime)
512 | {
513 |
514 | }
515 | else
516 | {
517 | //await ShowUselessMessagesTask();
518 | }
519 |
520 | MainWindow.ShellFrame.Navigate(typeof(MainShellPage));
521 |
522 | bypassWaitTime = false;
523 | }
524 |
525 | private void RevealPasswordCheck_Checked(object sender, RoutedEventArgs e)
526 | {
527 | PasswordBox.PasswordRevealMode = PasswordRevealMode.Visible;
528 | }
529 |
530 | private void RevealPasswordCheck_Unchecked(object sender, RoutedEventArgs e)
531 | {
532 | PasswordBox.PasswordRevealMode = PasswordRevealMode.Hidden;
533 | }
534 | }
535 | }
536 |
--------------------------------------------------------------------------------
/Pages/MainShellPage.xaml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
28 |
29 | 56,26,0,0
30 |
31 |
32 |
33 |
34 |
35 |
36 |
41 | 12
42 | 12,0
43 |
44 |
45 |
46 |
47 |
49 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
111 |
112 |
113 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/Pages/MainShellPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.UI.Xaml;
2 | using Microsoft.UI.Xaml.Controls;
3 | using Microsoft.UI.Xaml.Controls.Primitives;
4 | using Microsoft.UI.Xaml.Data;
5 | using Microsoft.UI.Xaml.Input;
6 | using Microsoft.UI.Xaml.Media;
7 | using Microsoft.UI.Xaml.Navigation;
8 | using FortniteLauncher.Services;
9 | using System;
10 | using System.Collections.Generic;
11 | using System.IO;
12 | using System.Linq;
13 | using System.Runtime.InteropServices.WindowsRuntime;
14 | using System.Threading;
15 | using Windows.Foundation;
16 | using Windows.Foundation.Collections;
17 | using WinUIEx;
18 | using static FortniteLauncher.Services.NavigationService;
19 |
20 | // To learn more about WinUI, the WinUI project structure,
21 | // and more about our project templates, see: http://aka.ms/winui-project-info.
22 |
23 | namespace FortniteLauncher.Pages
24 | {
25 | ///
26 | /// An empty page that can be used on its own or navigated to within a Frame.
27 | ///
28 | public sealed partial class MainShellPage : Page
29 | {
30 | public static string DisplayUsername;
31 |
32 | string _username;
33 |
34 | public static NavigationView STATIC_MainNavigation;
35 | public MainShellPage()
36 | {
37 | this.InitializeComponent();
38 | InitializeNavigationService(MainNavigation, MainBreadcrumb, RootFrame);
39 |
40 | _username = DisplayUsername;
41 |
42 | MainNavigation.SelectedItem = PlayPageItem;
43 |
44 | Globals.ChangePaneToggleBtnVisibility(true);
45 |
46 | }
47 |
48 | private void MainNavigation_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
49 | {
50 | if (args.IsSettingsSelected)
51 | {
52 | NavigationService.Navigate(typeof(SettingsPage), "Settings", true);
53 | }
54 | if ((args.SelectedItem as NavigationViewItem) == PlayPageItem)
55 | {
56 | NavigationService.Navigate(typeof(PlayPage), "Play", true);
57 | ChangeBreadcrumbVisibility(false);
58 | }
59 | if ((args.SelectedItem as NavigationViewItem) == DownloadsItem)
60 | {
61 | NavigationService.Navigate(typeof(DownloadsPage), "Downloads", true);
62 | }
63 | if ((args.SelectedItem as NavigationViewItem) == ItemShopItem)
64 | {
65 | NavigationService.Navigate(typeof(ItemShopPage), "Item Shop", true);
66 | }
67 | if ((args.SelectedItem as NavigationViewItem) == ServerStatusItem)
68 | {
69 | NavigationService.Navigate(typeof(ServerStatusPage), "Server Status", true);
70 | }
71 | ElementSoundPlayer.Play(ElementSoundKind.Invoke);
72 | }
73 |
74 | private void MainBreadcrumb_ItemClicked(BreadcrumbBar sender, BreadcrumbBarItemClickedEventArgs args)
75 | {
76 | if (args.Index < NavigationService.BreadCrumbs.Count - 1)
77 | {
78 | var crumb = (Breadcrumb)args.Item;
79 | crumb.NavigateToFromBreadcrumb(args.Index);
80 | }
81 | }
82 |
83 | private void PaneContent_Click(object sender, RoutedEventArgs e)
84 | {
85 | MainNavigation.SelectedItem = null;
86 | NavigationService.Navigate(typeof(SettingsPage), "Settings", true);
87 | }
88 |
89 | private void MainNavigation_Loaded(object sender, RoutedEventArgs e)
90 | {
91 | STATIC_MainNavigation = MainNavigation;
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/Pages/PlayPage.xaml:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
--------------------------------------------------------------------------------
/Pages/PlayPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using Amazon.Runtime.Internal.Endpoints.StandardLibrary;
2 | using CommunityToolkit.Labs.WinUI;
3 | using Microsoft.UI.Text;
4 | using Microsoft.UI.Xaml;
5 | using Microsoft.UI.Xaml.Controls;
6 | using Microsoft.UI.Xaml.Controls.Primitives;
7 | using Microsoft.UI.Xaml.Data;
8 | using Microsoft.UI.Xaml.Input;
9 | using Microsoft.UI.Xaml.Media;
10 | using Microsoft.UI.Xaml.Media.Imaging;
11 | using Microsoft.UI.Xaml.Navigation;
12 | using Microsoft.WindowsAppSDK.Runtime.Packages;
13 | using FortniteLauncher.Interop;
14 | using FortniteLauncher.Services;
15 | using System;
16 | using System.Collections.Generic;
17 | using System.Diagnostics;
18 | using System.IO;
19 | using System.Linq;
20 | using System.Net;
21 | using System.Runtime.InteropServices.WindowsRuntime;
22 | using System.Threading.Tasks;
23 | using Windows.Foundation;
24 | using Windows.Foundation.Collections;
25 | using Windows.System;
26 | using WinUIEx.Messaging;
27 |
28 | // To learn more about WinUI, the WinUI project structure,
29 | // and more about our project templates, see: http://aka.ms/winui-project-info.
30 |
31 | namespace FortniteLauncher.Pages
32 | {
33 | ///
34 | /// An empty page that can be used on its own or navigated to within a Frame.
35 | ///
36 | public sealed partial class PlayPage : Page
37 | {
38 | bool _isLaunchingTheGame = false;
39 | string _username = string.Empty;
40 |
41 | public static SettingsCard STATIC_MainLaunchCard;
42 |
43 | public PlayPage()
44 | {
45 | this.InitializeComponent();
46 | _username = "Hi, " + MainShellPage.DisplayUsername + "!";
47 | STATIC_MainLaunchCard = MainLaunchCard;
48 | if (personPicture.ProfilePicture == null) // dont work as expected
49 | {
50 | personPicture.ProfilePicture = new BitmapImage(new Uri("ms-appx:///Assets/PFP.png"));
51 | }
52 | //API.StartClient(); // to many risks on adding this
53 | image();
54 | }
55 |
56 | /*
57 | public static void ShowNotification(string titlee, string text)
58 | {
59 | try // it crashes so lets put it in a try ig
60 | {
61 | //this is a terrible way of doing it, but it works
62 | StackPanel panel = new StackPanel();
63 | panel.Spacing = 2;
64 |
65 | TextBlock title = new TextBlock();
66 | title.Text = titlee;
67 | title.FontWeight = FontWeights.Medium;
68 |
69 | TextBlock desc = new TextBlock();
70 | desc.Text = text;
71 |
72 | panel.Children.Add(title);
73 | panel.Children.Add(desc);
74 |
75 | Grid g = new Grid();
76 | ColumnDefinition def1 = new ColumnDefinition();
77 | ColumnDefinition def2 = new ColumnDefinition();
78 | def1.Width = GridLength.Auto;
79 | def2.Width = GridLength.Auto;
80 | g.ColumnDefinitions.Add(def1);
81 | g.ColumnDefinitions.Add(def2);
82 |
83 | FontIcon icon = new FontIcon();
84 | icon.VerticalAlignment = VerticalAlignment.Center;
85 | icon.Glyph = "\uE72E";
86 | icon.FontSize = 28;
87 | icon.Margin = new Thickness(0, 0, 12, 0);
88 |
89 | g.Children.Add(icon);
90 | g.Children.Add(panel);
91 |
92 | Grid.SetColumn(icon, 0);
93 | Grid.SetColumn(panel, 1);
94 |
95 | Notification.Show(g, 2500);
96 | }
97 | catch
98 | {
99 | // ignore the error maybe?
100 | }
101 | }
102 | */
103 | async void image()
104 | {
105 | while (Definitions.Email != null)
106 | {
107 | string url = await API.GetSkin();
108 | try
109 | {
110 | if (url == "Error")
111 | {
112 | BitmapImage image = new BitmapImage();
113 | image.UriSource = new Uri("http://fortnite-api.com/images/cosmetics/br/CID_001_Athena_Commando_F_Default/smallicon.png");
114 |
115 | personPicture.ProfilePicture = image;
116 | } else
117 | {
118 | BitmapImage image = new BitmapImage();
119 | image.UriSource = new Uri(url);
120 |
121 | personPicture.ProfilePicture = image;
122 | }
123 |
124 | }
125 | catch (Exception ex)
126 | {
127 | // idek
128 | DialogService.ShowSimpleDialog("Failed to get Profile Picture: " + ex.Message + " url: " + url, "Error");
129 | }
130 | await Task.Delay(10000);
131 | }
132 | }
133 | public async void LaunchBtn_Click(object sender, RoutedEventArgs e)
134 | {
135 | // idk
136 | /*
137 | while (Definitions.FinishedAPIRequest == false)
138 | {
139 | if (Definitions.FinishedAPIRequest == true) { break; }
140 | ((SettingsCard)sender).IsEnabled = false;
141 | ProgressRing r = new ProgressRing();
142 | r.IsIndeterminate = true;
143 |
144 | ((SettingsCard)sender).Content = r;
145 | await Task.Delay(3000);
146 | }
147 | */
148 | if (Definitions.BindPlayButton)
149 | {
150 | if (!Definitions.ConnectionFailedToAPI)
151 | {
152 | string RootDirectory = Definitions.RootDirectory;
153 | if (MainLaunchCard.Tag.ToString().Contains("Launch"))
154 | {
155 | if (Definitions.outdated == true && Definitions.limitguestfeatures == true)
156 | {
157 | DialogService.ShowSimpleDialog("Please update Exit Launcher to use this feature.", "Error");
158 | }
159 | else
160 | {
161 | if (_isLaunchingTheGame)
162 | {
163 | return;
164 | }
165 |
166 | _isLaunchingTheGame = true;
167 |
168 | ProgressRing r = new ProgressRing();
169 | r.IsIndeterminate = true;
170 |
171 | ((SettingsCard)sender).Content = r;
172 | string basefn = Definitions.FortnitePath;
173 | if (basefn == null)
174 | {
175 | if (Globals.m_config.FortnitePath != null)
176 | {
177 | basefn = Globals.m_config.FortnitePath;
178 | }
179 | else
180 | {
181 | DialogService.ShowSimpleDialog("Fortnite path is not set please check your installation and try again.", "Path Invalid");
182 | }
183 | }
184 | if (basefn != null)
185 | {
186 | if (!Definitions.AllowLaunchingAnyVersion)
187 | {
188 | string CheckFiles = await Anticheat.CheckForMods(basefn);
189 | bool VerifyClient = await Anticheat.VerifyClient(basefn);
190 | try
191 | {
192 | if (CheckFiles == "Success")
193 | {
194 | if (VerifyClient)
195 | {
196 | await Task.Delay(600); //delay for a little
197 | await Fortnite.Launch(basefn, Definitions.Email, Definitions.Password);
198 | _isLaunchingTheGame = false;
199 | }
200 | }
201 | else
202 | {
203 | _isLaunchingTheGame = false;
204 | ((SettingsCard)sender).Content = null;
205 | return;
206 | }
207 | }
208 |
209 | catch (Exception ex)
210 | {
211 | DialogService.ShowSimpleDialog("Failed to launch Fortnite: " + ex.Message, "Error");
212 | }
213 | }
214 | else
215 | {
216 | await Task.Delay(600); //delay for a little
217 |
218 | _isLaunchingTheGame = false;
219 | await Fortnite.Launch(basefn, Definitions.Email, Definitions.Password);
220 |
221 | }
222 | }
223 | }
224 | }
225 | else
226 | {
227 | try
228 | {
229 | Process[] gameProcesses = Process.GetProcessesByName("FortniteClient-Win64-Shipping");
230 | foreach (Process process in gameProcesses)
231 | {
232 | process.Kill();
233 | }
234 |
235 | }
236 | catch
237 | {
238 | // ignore
239 | }
240 | MainLaunchCard.Header = "Launch Season 4";
241 | MainLaunchCard.Description = "Launch Fortnite Chapter 2 Season 4 powered by Exit";
242 |
243 | FontIcon icon = new FontIcon();
244 | icon.Glyph = "\uE768";
245 | MainLaunchCard.HeaderIcon = icon;
246 |
247 | MainLaunchCard.Tag = "Launch";
248 | }
249 | }
250 | else
251 | {
252 | DialogService.ShowSimpleDialog("Failed to launch Fortnite the connection to the API failed, please restart the launcher and try again.", "Error");
253 | }
254 | }
255 | }
256 | public static void KillProcessByName(string processName)
257 | {
258 | try
259 | {
260 | Process[] processes = Process.GetProcessesByName(processName);
261 |
262 | foreach (Process process in processes)
263 | {
264 | process.Kill(); // Kill the process
265 | process.WaitForExit(); // Wait for the process to exit
266 | process.Dispose(); // Release resources associated with the process
267 | }
268 | }
269 | catch
270 | {
271 | // idk
272 | }
273 | }
274 | private void DiscordBtn_Click(object sender, RoutedEventArgs e)
275 | {
276 |
277 | }
278 |
279 | private void DonationsCard_Click(object sender, RoutedEventArgs e)
280 | {
281 | var uri = "https://Exitfn.sellix.io/";
282 | var psi = new System.Diagnostics.ProcessStartInfo();
283 | psi.UseShellExecute = true;
284 | psi.FileName = uri;
285 | System.Diagnostics.Process.Start(psi);
286 | }
287 |
288 | private void DiscordCard_Click(object sender, RoutedEventArgs e)
289 | {
290 | var uri = "https://discord.gg/exitfn";
291 | var psi = new System.Diagnostics.ProcessStartInfo();
292 | psi.UseShellExecute = true;
293 | psi.FileName = uri;
294 | System.Diagnostics.Process.Start(psi);
295 | }
296 | }
297 | }
298 |
--------------------------------------------------------------------------------
/Pages/ServerStatusPage.xaml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
23 |
24 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/Pages/ServerStatusPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using CommunityToolkit.Labs.WinUI;
2 | using Microsoft.UI.Xaml;
3 | using Microsoft.UI.Xaml.Controls;
4 | using Microsoft.UI.Xaml.Controls.Primitives;
5 | using Microsoft.UI.Xaml.Data;
6 | using Microsoft.UI.Xaml.Input;
7 | using Microsoft.UI.Xaml.Media;
8 | using Microsoft.UI.Xaml.Navigation;
9 | using FortniteLauncher.Services;
10 | using System;
11 | using System.Collections.Generic;
12 | using System.IO;
13 | using System.Linq;
14 | using System.Runtime.InteropServices.WindowsRuntime;
15 | using System.Threading.Tasks;
16 | using Windows.Foundation;
17 | using Windows.Foundation.Collections;
18 |
19 | // To learn more about WinUI, the WinUI project structure,
20 | // and more about our project templates, see: http://aka.ms/winui-project-info.
21 |
22 | namespace FortniteLauncher.Pages
23 | {
24 | ///
25 | /// An empty page that can be used on its own or navigated to within a Frame.
26 | ///
27 | public sealed partial class ServerStatusPage : Page
28 | {
29 | public enum Status
30 | {
31 | Online,
32 | Down,
33 | Unknown,
34 | Outdated
35 | }
36 | public enum ServerType //idk a better name
37 | {
38 | Backend,
39 | API,
40 | GameServer
41 | }
42 | public ServerStatusPage()
43 | {
44 | this.InitializeComponent();
45 |
46 | SetServerStatsAsync();
47 | }
48 |
49 | public async Task SetServerStatsAsync()
50 | {
51 | await GetStatus();
52 | }
53 |
54 | public async Task GetStatus()
55 | {
56 | if (Definitions.outdated == true && Definitions.limitguestfeatures == true)
57 | {
58 | DialogService.ShowSimpleDialog("Please update Exit Launcher to use this feature.", "Error");
59 | }
60 | else
61 | {
62 | string Connection = await API.Connect();
63 | string BackendStatus = await API.BackendStatus();
64 | bool hasUpdates = await CheckForUpdatesAPI.checkforupdatesAsync();
65 | if (Connection == "Success")
66 | {
67 | if (hasUpdates == false)
68 | {
69 | SetStatus(ServerType.API, Status.Outdated);
70 | }
71 | else
72 | {
73 | SetStatus(ServerType.API, Status.Online);
74 | }
75 | if (BackendStatus == "Success")
76 | {
77 | SetStatus(ServerType.Backend, Status.Online);
78 | }
79 | else if (BackendStatus == "Error")
80 | {
81 | SetStatus(ServerType.Backend, Status.Down);
82 | }
83 | else
84 | {
85 | DialogService.ShowSimpleDialog("Unknown Error occured while checking backend status.", "Error");
86 | }
87 | }
88 | }
89 | }
90 |
91 | void SetStatus(ServerType serverType, Status Status)
92 | {
93 | switch (serverType)
94 | {
95 | case ServerType.Backend:
96 | switch (Status)
97 | {
98 | case Status.Online:
99 | BackendStatusCard.Description = "Online";
100 | BackendBadge.Style = Application.Current.Resources["SuccessDotInfoBadgeStyle"] as Style;
101 | break;
102 | case Status.Unknown:
103 | BackendStatusCard.Description = "Unknown";
104 | BackendBadge.Style = Application.Current.Resources["InformationalDotInfoBadgeStyle"] as Style;
105 | break;
106 | case Status.Down:
107 | BackendStatusCard.Description = "Down";
108 | BackendBadge.Style = Application.Current.Resources["CriticalDotInfoBadgeStyle"] as Style;
109 | break;
110 | }
111 | break;
112 | }
113 | }
114 | private async void ReloadButton_Click(object sender, RoutedEventArgs e)
115 | {
116 | await GetStatus();
117 | }
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/Pages/SettingsPage.xaml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/Pages/SettingsPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.UI;
2 | using Microsoft.UI.Xaml;
3 | using Microsoft.UI.Xaml.Controls;
4 | using Microsoft.UI.Xaml.Controls.Primitives;
5 | using Microsoft.UI.Xaml.Data;
6 | using Microsoft.UI.Xaml.Input;
7 | using Microsoft.UI.Xaml.Media;
8 | using Microsoft.UI.Xaml.Navigation;
9 | using Microsoft.UI.Xaml.Shapes;
10 | using FortniteLauncher.Core;
11 | using FortniteLauncher.Interop;
12 | using FortniteLauncher.Services;
13 | using System;
14 | using System.Collections.Generic;
15 | using System.Diagnostics;
16 | using System.IO;
17 | using System.Linq;
18 | using System.Net;
19 | using System.Runtime.InteropServices.WindowsRuntime;
20 | using System.Threading.Tasks;
21 | using Windows.Foundation;
22 | using Windows.Foundation.Collections;
23 | using WinUIEx;
24 |
25 | // To learn more about WinUI, the WinUI project structure,
26 | // and more about our project templates, see: http://aka.ms/winui-project-info.
27 |
28 | namespace FortniteLauncher.Pages
29 | {
30 | ///
31 | /// An empty page that can be used on its own or navigated to within a Frame.
32 | ///
33 | public sealed partial class SettingsPage : Page
34 | {
35 | string _version = Globals.Version;
36 | bool _isInitializingPage = false;
37 | public SettingsPage()
38 | {
39 | this.InitializeComponent();
40 | if (Definitions.outdated == true && Definitions.limitguestfeatures == true)
41 | {
42 | LogoutBtn.Visibility = Visibility.Collapsed;
43 | }
44 | }
45 |
46 | private void Page_Loaded(object sender, RoutedEventArgs e)
47 | {
48 | if (Definitions.outdated == true && Definitions.limitguestfeatures == true)
49 | {
50 | Refresh.Visibility = Visibility.Collapsed;
51 | }
52 |
53 | //set sound
54 | if (Globals.m_config.IsSoundEnabled)
55 | {
56 | SoundSwitch.IsOn = true;
57 | }
58 | }
59 |
60 | private void SoundSwitch_Toggled(object sender, RoutedEventArgs e)
61 | {
62 | if (_isInitializingPage)
63 | {
64 | return;
65 | }
66 |
67 | if (((ToggleSwitch)sender).IsOn)
68 | {
69 | ElementSoundPlayer.State = ElementSoundPlayerState.On;
70 | Globals.m_config.IsSoundEnabled = true;
71 | }
72 | else
73 | {
74 | ElementSoundPlayer.State = ElementSoundPlayerState.Off;
75 | Globals.m_config.IsSoundEnabled = false;
76 | }
77 |
78 | Settings.SaveSettings();
79 | }
80 |
81 | private async void LogoutBtn_Click(object sender, RoutedEventArgs e)
82 | {
83 | Definitions.LoggedOut = true;
84 | ((Button)sender).IsEnabled = false;
85 | ProgressRing r =new ProgressRing();
86 | r.IsIndeterminate = true;
87 | r.Foreground = new SolidColorBrush(Colors.White);
88 |
89 | ((Button)sender).Content = r;
90 |
91 | //((Button)sender).Background = new Button().Background;
92 |
93 | //here clear variables and anything else that is needed
94 |
95 | //await Task.Delay(250);//temporary
96 |
97 | MainWindow.ShellFrame.Navigate(typeof(LoginPage));
98 | ((Button)sender).IsEnabled = true;
99 | }
100 |
101 | private async void CheckForUpdates_Click(object sender, RoutedEventArgs e)
102 | {
103 | if (Definitions.outdated == true && Definitions.limitguestfeatures == true)
104 | {
105 | DialogService.ShowSimpleDialog("Please update Exit Launcher to use this feature.", "Error");
106 | }
107 | else
108 | {
109 | await CheckForUpdatesAPI.Start();
110 | if (Definitions.APIversion != null)
111 | {
112 | if (Definitions.APIversion != Definitions.CurrentVersion)
113 | {
114 | DialogService.ShowSimpleDialog("New update detected current version: " + Definitions.CurrentVersion + " Latest version: " + Definitions.APIversion + " please update to continue using Exit launcher.", "New update");
115 | Environment.Exit(1);
116 | }
117 | else
118 | {
119 | DialogService.ShowSimpleDialog("You are up to date!", "No new update");
120 | }
121 | }
122 | else
123 | {
124 | DialogService.ShowSimpleDialog("Failed to get latest version error: null.", "Error");
125 | }
126 | }
127 | }
128 |
129 | private async void Refresh_Click(object sender, RoutedEventArgs e)
130 | {
131 | Definitions.RefreshToken = true;
132 | ((Button)sender).IsEnabled = false;
133 | ProgressRing r = new ProgressRing();
134 | r.IsIndeterminate = true;
135 |
136 | ((Button)sender).Content = r;
137 |
138 | //here clear variables and anything else that is needed
139 |
140 | await Task.Delay(250);//temporary
141 |
142 | MainWindow.ShellFrame.Navigate(typeof(LoginPage));
143 | ((Button)sender).IsEnabled = true;
144 | }
145 |
146 | private async void RemovePatch_Click(object sender, RoutedEventArgs e)
147 | {
148 | string FNPath = Globals.m_config.FortnitePath;
149 |
150 | try
151 | {
152 | KillProcessByName("FortniteClient-Win64-Shipping");
153 | KillProcessByName("ExitClient-Win64-Shipping");
154 | KillProcessByName("FortniteClient-Win64-Shipping_EAC");
155 | KillProcessByName("FortniteClient-Win64-Shipping_BE");
156 | KillProcessByName("FortniteLauncher");
157 |
158 | string easyAntiCheatPath = System.IO.Path.Combine(FNPath, "EasyAntiCheat");
159 | if (Directory.Exists(easyAntiCheatPath))
160 | {
161 | Directory.Delete(easyAntiCheatPath, true);
162 | }
163 |
164 | string ExitEACPath = System.IO.Path.Combine(FNPath, "ExitClient-Win64-Shipping.exe");
165 | if (File.Exists(ExitEACPath))
166 | {
167 | File.Delete(ExitEACPath);
168 | }
169 |
170 | string aftermathDllPath = System.IO.Path.Combine(FNPath, "Engine", "Binaries", "ThirdParty", "NVIDIA", "NVaftermath", "Win64", "GFSDK_Aftermath_Lib.x64.dll");
171 | if (File.Exists(aftermathDllPath))
172 | {
173 | File.Delete(aftermathDllPath);
174 | using (WebClient webClient = new WebClient())
175 | {
176 | //await webClient.DownloadFileTaskAsync(Definitions.GFSDKUrl, aftermathDllPath);
177 | }
178 | DialogService.ShowSimpleDialog("Patch was removed successfully.", "Success");
179 | }
180 | }
181 | catch (Exception ex)
182 | {
183 | DialogService.ShowSimpleDialog("An error occurred: " + ex.Message, "Error");
184 | }
185 | }
186 |
187 | static void KillProcessByName(string processName)
188 | {
189 | Process[] processes = Process.GetProcessesByName(processName);
190 |
191 | foreach (Process process in processes)
192 | {
193 | try
194 | {
195 | process.Kill();
196 | }
197 | catch
198 | {
199 | }
200 | }
201 | }
202 | }
203 | }
204 |
--------------------------------------------------------------------------------
/Properties/launchSettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "profiles": {
3 | "FortniteLauncher (Package)": {
4 | "commandName": "MsixPackage"
5 | },
6 | "FortniteLauncher (Unpackaged)": {
7 | "commandName": "Project"
8 | }
9 | }
10 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Exit-Launcher
2 | **NOBODY** is free to copy, modify, publish, use, compile, sell, or distribute this software, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means other than the **OWNERS** of "Exit".
3 |
4 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
5 |
--------------------------------------------------------------------------------
/Services/DialogService.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.UI.Xaml.Controls;
2 | using Microsoft.UI.Xaml;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 | using Microsoft.UI.Xaml.Media;
9 | using System.Threading;
10 |
11 | namespace FortniteLauncher.Services
12 | {
13 | public class DialogService
14 | {
15 | public static async void ShowSimpleDialog(object Content, string Title)
16 | {
17 | try {
18 | //there can only be one dialog open at once, so if it exist just close it
19 | var openedpopups = VisualTreeHelper.GetOpenPopups(Globals.m_window);
20 | foreach (var popup in openedpopups)
21 | {
22 | if (popup.Child is ContentDialog)
23 | {
24 | return;
25 | }
26 | }
27 | ContentDialog dialog = new ContentDialog();
28 | dialog.XamlRoot = Globals.m_window.Content.XamlRoot;
29 | dialog.Style = Application.Current.Resources["DefaultContentDialogStyle"] as Style;
30 | dialog.Title = Title;
31 | dialog.Content = Content;
32 |
33 | dialog.CloseButtonText = "OK";
34 |
35 | await dialog.ShowAsync();
36 | } catch
37 | {
38 | // ignore the error maybe?
39 | }
40 | }
41 |
42 | public static async void CurcleLoading(string message)
43 | {
44 | try
45 | {
46 | // Close any existing dialogs
47 | var openedpopups = VisualTreeHelper.GetOpenPopups(Globals.m_window);
48 | foreach (var popup in openedpopups)
49 | {
50 | if (popup.Child is ContentDialog)
51 | {
52 | return;
53 | }
54 | }
55 |
56 | // Create a ContentDialog
57 | ContentDialog dialog = new ContentDialog();
58 | dialog.XamlRoot = Globals.m_window.Content.XamlRoot;
59 | dialog.Style = Application.Current.Resources["DefaultContentDialogStyle"] as Style;
60 | dialog.CloseButtonText = ""; // No close button
61 |
62 | // Create a StackPanel to hold the ProgressRing and TextBlock
63 | StackPanel stackPanel = new StackPanel();
64 | stackPanel.Orientation = Orientation.Vertical;
65 |
66 | // Add a ProgressRing
67 | ProgressRing progressRing = new ProgressRing();
68 | progressRing.IsActive = true;
69 | progressRing.HorizontalAlignment = HorizontalAlignment.Center;
70 | progressRing.Margin = new Thickness(0, 0, 0, 10); // Adjust margin as needed
71 | stackPanel.Children.Add(progressRing);
72 |
73 | // Add a TextBlock with the specified message
74 | TextBlock textBlock = new TextBlock();
75 | textBlock.Text = message;
76 | textBlock.Margin = new Thickness(0, 0, 0, 0); // Adjust margin as needed
77 | textBlock.HorizontalAlignment = HorizontalAlignment.Center;
78 | stackPanel.Children.Add(textBlock);
79 |
80 | // Set the Content of the dialog to the StackPanel
81 | dialog.Content = stackPanel;
82 |
83 | // Measure and arrange the dialog's content to fit its size
84 | dialog.UpdateLayout();
85 |
86 | // Calculate the desired width and height based on content size
87 | double desiredWidth = stackPanel.DesiredSize.Width;
88 | double desiredHeight = stackPanel.DesiredSize.Height;
89 |
90 | // Set the dialog's size based on the desired width and height
91 | dialog.Width = desiredWidth;
92 | dialog.Height = desiredHeight;
93 |
94 | // Show the dialog
95 | await dialog.ShowAsync();
96 | }
97 | catch
98 | {
99 | // Ignore the error maybe?
100 | }
101 | }
102 |
103 |
104 | public static async Task YesOrNoDialog(object Content, string Title)
105 | {
106 | try
107 | {
108 | // There can only be one dialog open at once, so if it exists, just close it
109 | var openedPopups = VisualTreeHelper.GetOpenPopups(Globals.m_window);
110 | foreach (var popup in openedPopups)
111 | {
112 | if (popup.Child is ContentDialog)
113 | {
114 | return false; // Return false to indicate the dialog wasn't shown
115 | }
116 | }
117 |
118 | ContentDialog dialog = new ContentDialog();
119 | dialog.XamlRoot = Globals.m_window.Content.XamlRoot;
120 | dialog.Style = Application.Current.Resources["DefaultContentDialogStyle"] as Style;
121 | dialog.Title = Title;
122 | dialog.Content = Content;
123 |
124 | dialog.PrimaryButtonText = "Yes";
125 | dialog.CloseButtonText = "No";
126 |
127 | ContentDialogResult result = await dialog.ShowAsync();
128 | return result == ContentDialogResult.Primary; // Return true for "Yes" and false for "No"
129 | }
130 | catch
131 | {
132 | return false;
133 | }
134 | }
135 |
136 | /*
137 | public static async Task DownloadProgressDialog(CancellationTokenSource cancellationTokenSource)
138 | {
139 | try
140 | {
141 | var openedPopups = VisualTreeHelper.GetOpenPopups(Globals.m_window);
142 | foreach (var popup in openedPopups)
143 | {
144 | if (popup.Child is ContentDialog)
145 | {
146 | return false; // Return false to indicate the dialog wasn't shown
147 | }
148 | }
149 |
150 | ContentDialog dialog = new ContentDialog();
151 | dialog.XamlRoot = Globals.m_window.Content.XamlRoot;
152 | dialog.Style = Application.Current.Resources["DefaultContentDialogStyle"] as Style;
153 | dialog.Title = "Downloading";
154 |
155 | StackPanel contentPanel = new StackPanel();
156 | contentPanel.VerticalAlignment = VerticalAlignment.Stretch;
157 |
158 | ProgressBar progressBar = new ProgressBar();
159 | progressBar.IsIndeterminate = true; // You can set this to false and update the value for a determinate progress bar
160 | contentPanel.Children.Add(progressBar);
161 |
162 | Button cancelButton = new Button();
163 | cancelButton.Content = "Cancel";
164 | cancelButton.Style = Application.Current.Resources["CancelButtonStyle"] as Style; // Create a style in your application resources
165 | cancelButton.Click += (sender, args) =>
166 | {
167 | cancellationTokenSource.Cancel(); // Cancel the download operation
168 | dialog.Hide();
169 | };
170 | contentPanel.Children.Add(cancelButton);
171 |
172 | dialog.Content = contentPanel;
173 |
174 | ContentDialogResult result = await dialog.ShowAsync();
175 | return result == ContentDialogResult.Primary; // Return true for "Yes" (download completed) and false for "No" (download canceled)
176 | }
177 | catch
178 | {
179 | return false;
180 | }
181 | }
182 | */
183 |
184 | public static ContentDialog CreateStyledContentDialog()
185 | {
186 | ContentDialog dialog = new ContentDialog();
187 | dialog.XamlRoot = Globals.m_window.Content.XamlRoot;
188 | dialog.Style = Application.Current.Resources["DefaultContentDialogStyle"] as Style;
189 |
190 | return dialog;
191 | }
192 | }
193 | }
194 |
--------------------------------------------------------------------------------
/Services/NavigationService.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.UI.Xaml.Controls;
2 | using Microsoft.UI.Xaml.Media.Animation;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Collections.ObjectModel;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Threading.Tasks;
9 |
10 | namespace FortniteLauncher.Services
11 | {
12 | public class NavigationService
13 | {
14 | #region Classes
15 | //thanks to https://github.com/microsoft/devhome/blob/main/settings/DevHome.Settings/Models/Breadcrumb.cs#L10
16 | public class Breadcrumb
17 | {
18 | public Breadcrumb(string label, Type page)
19 | {
20 | Label = label;
21 | Page = page;
22 | }
23 | public string Label { get; }
24 |
25 | public Type Page { get; }
26 |
27 | public override string ToString() => Label;
28 |
29 | public void NavigateToFromBreadcrumb(int BreadcrumbItemIndex)
30 | {
31 | NavigationService.NavigateInternal(Page, BreadcrumbItemIndex);
32 | }
33 | }
34 | #endregion
35 |
36 | #region Properties
37 | public static NavigationView MainNavigation { get; private set; }
38 | public static BreadcrumbBar MainBreadcrumb { get; private set; }
39 |
40 | public static Frame MainFrame { get; private set; }
41 |
42 | public static ObservableCollection BreadCrumbs = new ObservableCollection();
43 | #endregion
44 |
45 | #region Constructor
46 | public static void InitializeNavigationService(NavigationView navigationView, BreadcrumbBar breadcrumbBar, Frame frame)
47 | {
48 | MainNavigation = navigationView;
49 | MainBreadcrumb = breadcrumbBar;
50 | MainFrame = frame;
51 | }
52 | #endregion
53 |
54 | #region Private Functions
55 | private static void UpdateBreadcrumb()
56 | {
57 | MainBreadcrumb.ItemsSource = BreadCrumbs;
58 | }
59 | private static void NavigateInternal(Type page, int BreadcrumbBarIndex)
60 | {
61 | SlideNavigationTransitionInfo info = new SlideNavigationTransitionInfo();
62 | info.Effect = SlideNavigationTransitionEffect.FromLeft;
63 | MainFrame.Navigate(page, null, info);
64 |
65 | int indexToRemoveAfter = BreadcrumbBarIndex;
66 |
67 | if (indexToRemoveAfter < BreadCrumbs.Count - 1)
68 | {
69 | int itemsToRemove = BreadCrumbs.Count - indexToRemoveAfter - 1;
70 |
71 | for (int i = 0; i < itemsToRemove; i++)
72 | {
73 | BreadCrumbs.RemoveAt(indexToRemoveAfter + 1);
74 | }
75 | }
76 | }
77 | #endregion
78 |
79 | #region Public Functions
80 | public static void Navigate(Type TargetPageType, string BreadcrumbItemLabel, bool ClearNavigation)
81 | {
82 | if (ClearNavigation)
83 | {
84 | BreadCrumbs.Clear();
85 | MainFrame.BackStack.Clear();
86 | }
87 | BreadCrumbs.Add(new Breadcrumb(BreadcrumbItemLabel, TargetPageType));
88 |
89 | SlideNavigationTransitionInfo info = new SlideNavigationTransitionInfo();
90 | info.Effect = SlideNavigationTransitionEffect.FromLeft;
91 | if (ClearNavigation)
92 | {
93 | //info.Effect = SlideNavigationTransitionEffect.FromBottom; //navigating fresh
94 | }
95 | else
96 | {
97 | //info.Effect = SlideNavigationTransitionEffect.FromRight;
98 | }
99 |
100 | UpdateBreadcrumb();
101 | ChangeBreadcrumbVisibility(true);
102 |
103 | MainFrame.Navigate(TargetPageType);
104 | }
105 |
106 | public static void ChangeBreadcrumbVisibility(bool IsBreadcrumbVisible)
107 | {
108 | if (IsBreadcrumbVisible)
109 | {
110 | MainBreadcrumb.Visibility = Microsoft.UI.Xaml.Visibility.Visible;
111 | MainNavigation.AlwaysShowHeader = true;
112 | }
113 | else
114 | {
115 | MainBreadcrumb.Visibility = Microsoft.UI.Xaml.Visibility.Collapsed;
116 | MainNavigation.AlwaysShowHeader = false;
117 | }
118 | }
119 | #endregion
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/Services/ThemeService.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.UI.Xaml;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | namespace FortniteLauncher.Services
9 | {
10 | public class ThemeService
11 | {
12 | public static void ChangeTheme(ElementTheme theme)
13 | {
14 | if (Globals.m_window.Content is FrameworkElement frameworkElement)
15 | {
16 | //because of the last- minute change of the colors of the launcher, i have to do this as it breaks the color
17 | //frameworkElement.RequestedTheme = theme;
18 | }
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | PerMonitorV2
18 |
19 |
20 |
--------------------------------------------------------------------------------