Compare commits

...
334 Commits
Author SHA1 Message Date
amacocian 7347de58af Build editor improvements (Closes #776) (#986) 2025-05-16 13:41:10 +02:00
amacocian f1ee932f23 EventsView scroll to current/upcoming event (Closes #777) (#985) 2025-05-16 13:41:10 +02:00
amacocian cdbc81e310 Performance improvements to Build Synchronization View (Closes #980) (#984) 2025-05-16 13:41:10 +02:00
amacocian 629c6ed14f Support for ReShade latest version (Closes #926) (#983) 2025-05-16 13:41:10 +02:00
amacocian 6577db54bc Update README (#982) 2025-05-16 13:41:10 +02:00
amacocian 926e9b7b48 Release 0.9.9.71 (#981) 2025-05-16 13:41:10 +02:00
amacocian c8433210e3 Hotfix for missing DXVK (#978) 2025-05-15 16:43:07 +02:00
amacocian 3274405c51 Release 0.9.9.70 (Closes #976) (#977) 2025-05-15 16:43:07 +02:00
amacocian 01bde80c39 Use latest DXVK binaries (#974) 2025-05-15 14:18:23 +02:00
amacocian 3f810b8a94 Launch Configurations can select any available executable (Closes #970) (#973) 2025-05-15 14:18:23 +02:00
amacocian 5d7ba2598f DXVK support (Closes #231) (#972) 2025-05-15 14:18:23 +02:00
amacocian 670d6bcbd5 Bump version (#971) 2025-05-15 14:18:23 +02:00
amacocian 9690d649fa Fix plugin example (#968) 2025-05-14 16:15:27 +02:00
amacocian 821ce69547 Show vials of dye in price quotes view (Closes #966) (#967) 2025-05-14 16:15:27 +02:00
amacocian 4f524ada67 Change executable checkmark to foreground color (Closes #774) (#965) 2025-05-14 16:15:27 +02:00
amacocian 0c2234f31b Disable executables during update (Closes #779) (#964) 2025-05-14 16:15:27 +02:00
amacocian 70085efd39 Make AccountsView and ExecutablesView scrollable (Closes #956) (#963) 2025-05-14 16:15:27 +02:00
amacocian bfa2128868 Move Accounts, Executables and LaunchConfigurations on the first positions under Settings (Closes #957) (#962) 2025-05-14 16:15:27 +02:00
amacocian 9b0da9b13c Improve startup speed and responsiveness (Closes #959) (#961) 2025-05-14 16:15:27 +02:00
amacocian 721ee8e494 Huge application refactoring to better support plugins (#960)
* Move shared code to Shared project
* Move from Realm to Squealify
* Rename Daybreak.Shared namespaces
* Setup API project to expose a test API
2025-05-14 16:15:27 +02:00
amacocian 5458db891f Release 0.9.9.68 (#958) 2025-05-14 16:15:27 +02:00
amacocian 9d9c15d0f6 Update dependencies (#954) 2025-05-07 12:01:57 +02:00
amacocian 4f49fc1cdf Expose API for creating menu buttons (#953) 2025-05-07 12:01:57 +02:00
amacocian 7efc7ba698 Release 0.9.9.67 (#952) 2025-05-07 12:01:57 +02:00
amacocian a79a6eae98 Bugfix greyed-out launch button (#949) 2025-04-30 19:20:26 +02:00
amacocian 0801256f4c Release 0.9.9.66 (#948) 2025-04-30 19:20:26 +02:00
amacocian e0799dd100 Remove redundant operations on launch UI. Improve UI performance (#946) 2025-04-30 18:48:03 +02:00
amacocian 24f4607899 Release 0.9.9.65 (#945) 2025-04-30 18:48:03 +02:00
amacocian 7aee0dfc16 Bugfix for multi-launch UI freezes (Closes #941) (#943) 2025-04-29 15:05:45 +02:00
amacocian 5fcb2314bc Release 0.9.9.64 (#942) 2025-04-29 15:05:45 +02:00
amacocian f218b89f6c Match Guildwars folder name structures (#938) 2025-04-27 16:01:22 +02:00
amacocian cc607b37c9 Release 0.9.9.63 (#937) 2025-04-27 16:01:22 +02:00
amacocian f80ea8cf0c Inject toolbox before GW initialization (#935) (#927) 2025-04-26 15:48:54 +02:00
amacocian 39f6707d23 Release 0.9.9.62 (#934) 2025-04-26 15:48:54 +02:00
amacocian eb11029ece Update pipeline runtimes (#933) 2025-04-25 02:42:36 +02:00
amacocian 4583b5b2d3 Fix toolbox injection (Closes #927) (#931) 2025-04-25 02:42:36 +02:00
amacocian 8c01377667 Update .NET9 runtime (#930) 2025-04-25 02:42:36 +02:00
amacocian 9a130d71dd Release 0.9.9.61 (#929) 2025-04-25 02:42:36 +02:00
amacocian 018ed6c5b5 Update dependencies (#928) 2025-04-25 02:42:36 +02:00
amacocianandGitHub cb48248c82 Change VirusTotal publish folder (#913) 2024-12-11 17:18:54 +01:00
amacocianandGitHub e1284375e2 Add debugging info to CD pipeline (#912) 2024-12-11 12:34:00 +00:00
amacocianandGitHub d38d620a84 Add VirusTotal scanning to CD pipeline (#911) 2024-12-11 11:36:39 +00:00
amacocian ce810dafab Support for toolbox builds (#908)
Closes #866
2024-12-10 14:50:59 +01:00
amacocian aabc98e4fc Build template metadata with support for hero positions. Closes #906 (#907) 2024-12-10 14:50:59 +01:00
amacocian 7eb0b7cc4f Release 0.9.9.60 (#905) 2024-12-10 14:50:59 +01:00
amacocian f1eb829ac4 Fix non-persistent notifications showing up after expiring. Closes #901 (#903) 2024-12-07 15:37:53 +01:00
amacocian 4b03a5a16f Increase memory scanner responsiveness (#902) 2024-12-07 15:37:53 +01:00
amacocian 71c90100be Fix memory scanner deadlock. Closes #899 (#900) 2024-12-07 15:37:53 +01:00
amacocian ee512d130d Fix launch button text when Focus View is disabled. Closes #897 (#898) 2024-12-07 15:37:53 +01:00
amacocian 03d0759e57 Release 0.9.9.59 (#896) 2024-12-07 15:37:53 +01:00
amacocian 0db7628d66 Cleanup GWCA dependencies (#895) 2024-12-06 21:19:01 +01:00
amacocian d1d1ba6c08 Fix build pipelines (#894) 2024-12-06 21:19:01 +01:00
amacocian d16a88a9bc Remove submodules file (#893) 2024-12-06 21:19:01 +01:00
amacocian a9d93f4162 Update dependencies (#891) 2024-12-06 21:19:01 +01:00
amacocian 632b5a55ac Remove GWCA (#890) Closes #889 #887 2024-12-06 21:19:01 +01:00
amacocian 6424505631 Release 0.9.9.58 (#888) 2024-12-06 21:19:01 +01:00
amacocian dfc1d3ba0a View for Guild Wars Party Search (#880)
Closes #877
2024-11-22 20:19:04 +01:00
amacocian 5bee88016d Upgrade vulnerable testing package (#879) 2024-11-22 20:19:04 +01:00
amacocian 5a37250680 Release 0.9.9.57 (#878) 2024-11-22 20:19:04 +01:00
amacocian 1c4ccb9fa3 Update dependencies (#874) 2024-11-22 15:09:42 +01:00
amacocian 8403dadca7 Patch GWCA module to not rely on the GW Window to start the http server. To be reverted once GWCA is patched (#871) (#873) 2024-11-22 15:09:42 +01:00
amacocian 4ac4cb0886 Check and update toolbox version (#872) 2024-11-22 15:09:42 +01:00
amacocian 74f13d2447 Update GWCA (#869) 2024-11-22 15:09:42 +01:00
amacocian bf53793729 Release 0.9.9.56 (#868) 2024-11-22 15:09:42 +01:00
amacocian e69dbf6791 Fix error test (#864) 2024-11-17 16:25:36 +01:00
amacocian a0eafa8a13 Setup button for bug reporting (#862)
Overhaul bug exception window
Closes #784
2024-11-17 16:25:36 +01:00
amacocian b0a236beb4 Use safe DateTime conversion (#861) 2024-11-17 16:25:36 +01:00
amacocian c10b81f3a1 Release 0.9.9.55 (#860) 2024-11-17 16:25:36 +01:00
amacocian 6cd51d6584 Fix theme sync (#858)
Closes #857
2024-11-16 00:16:40 +01:00
amacocian a283117cc8 Remove Minimap and InventoryComponent (#856)
Closes #855
2024-11-16 00:16:40 +01:00
amacocian 329e64232c Stop spamming when datetime conversion fails. This is a temporary fix for the spam (#854)
Closes #852
2024-11-16 00:16:40 +01:00
amacocian feb3c9042e Release 0.9.9.54 (#853) 2024-11-16 00:16:40 +01:00
amacocian 71f15f56a4 Update dependencies (#850) 2024-11-13 15:10:02 +01:00
amacocian d37951b832 Update GWCA (#849) 2024-11-13 15:10:02 +01:00
amacocian 908a149df4 Release 0.9.9.53 (#848) 2024-11-13 15:10:02 +01:00
amacocian 38cf140dfa Update GWCA (#838) 2024-10-23 22:57:08 +02:00
amacocian d13e1a2d08 Migrate db engine to Realm (#837) 2024-10-23 22:57:08 +02:00
amacocian a0c7842b84 Update dependencies (#836) 2024-10-23 22:57:08 +02:00
amacocian de13b68633 Release 0.9.9.52 (#835) 2024-10-23 22:57:08 +02:00
amacocian f289602068 Update dependencies - fixes critical System.Text.Json vulnerability (#831) 2024-10-10 12:01:01 +02:00
amacocian 15f4ee8979 Release 0.9.9.51 (#830) 2024-10-10 12:01:01 +02:00
amacocian d826dea457 Use sell quotes. Add sell prices and buy prices to trade quote view (#825) 2024-10-07 11:44:47 +02:00
amacocian b89a6666a3 Update dependencies and replace deprecated packages (#824) 2024-10-07 11:44:47 +02:00
amacocian 1dc69fd0c2 Release 0.9.9.50 (#823) 2024-10-07 11:44:47 +02:00
amacocian 5005b07f09 Update GWCA module (#819) 2024-09-27 17:37:40 +02:00
amacocian 0b692165e0 Update dependencies (#818) 2024-09-27 17:37:40 +02:00
amacocian ffee0fdf4c Release 0.9.9.49 (#817) 2024-09-27 17:37:40 +02:00
amacocian 72b4cd5470 Update GWCA (#808) 2024-08-20 17:34:59 +02:00
dependabot[bot]amacociandependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
dc9be53ace Bump MSTest.TestAdapter from 3.5.0 to 3.5.2 (#795)
Bumps [MSTest.TestAdapter](https://github.com/microsoft/testfx) from 3.5.0 to 3.5.2.
- [Release notes](https://github.com/microsoft/testfx/releases)
- [Changelog](https://github.com/microsoft/testfx/blob/main/docs/Changelog.md)
- [Commits](https://github.com/microsoft/testfx/compare/v3.5.0...v3.5.2)

---
updated-dependencies:
- dependency-name: MSTest.TestAdapter
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Macocian Alexandru Victor <amacocian@yahoo.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Macocian Alexandru Victor <amacocian@yahoo.com>
2024-08-20 17:34:59 +02:00
dependabot[bot]amacociandependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
3a8a6b0f7f Bump MSTest.TestFramework from 3.5.0 to 3.5.2 (#797)
Bumps [MSTest.TestFramework](https://github.com/microsoft/testfx) from 3.5.0 to 3.5.2.
- [Release notes](https://github.com/microsoft/testfx/releases)
- [Changelog](https://github.com/microsoft/testfx/blob/main/docs/Changelog.md)
- [Commits](https://github.com/microsoft/testfx/compare/v3.5.0...v3.5.2)

---
updated-dependencies:
- dependency-name: MSTest.TestFramework
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-20 17:34:59 +02:00
amacocian 7cdd0534f6 Set version checker as first mod in the list (#807)
Closes #778
2024-08-20 17:34:59 +02:00
amacocian 4b14ab9312 Add database cleanup (#806)
Closes #791
2024-08-20 17:34:59 +02:00
amacocian 57e1ddb8da Release 0.9.9.48 (#805) 2024-08-20 17:34:59 +02:00
amacocian c7609c0f7e Update dependencies (#803) 2024-08-20 16:34:04 +02:00
amacocian 1eca8021d2 Fixes for stuttering on image and notification load (#802) 2024-08-20 16:34:04 +02:00
amacocian 0077f35c4d Fix a bug in credentials migrator that would delete newly created credentials (#801) 2024-08-20 16:34:04 +02:00
amacocian 28b0a0a138 Release 0.9.9.47 (#800) 2024-08-20 16:34:04 +02:00
amacocian cc7ce92013 Update dependencies (#789) 2024-07-18 12:15:25 +03:00
amacocian 5bd02e56ee Ignore operation canceled exceptions (#788) 2024-07-18 12:15:25 +03:00
amacocian 8c7cd0a562 Bugfix for executable paths exception (#787) 2024-07-18 12:15:25 +03:00
amacocian 3ab3f72366 Release 0.9.9.46 (#785) 2024-07-18 12:15:25 +03:00
amacocian 733883a6c2 Check executables for fixes and updates (Closes #763) (#772) 2024-07-07 16:55:34 +03:00
amacocian d1ed8aeaf6 Fix GWCA module (#771) 2024-07-07 16:55:34 +03:00
amacocian 66ad44b8ce Update GWCA (#770) 2024-07-07 16:55:34 +03:00
amacocian 18e51ae408 Fix Nahpui Quarter missing id (Closes #761) (#769) 2024-07-07 16:55:34 +03:00
amacocian 06940dbf38 Update dependencies (#768) 2024-07-07 16:55:34 +03:00
amacocian 875b29f8ba Daybreak maintains and updates executables (#767) 2024-07-07 16:55:34 +03:00
amacocian a953c3a0d3 Release 0.9.9.45 (#766) 2024-07-07 16:55:34 +03:00
amacocian ce198fcfc9 Update GWCA (#759) 2024-06-11 15:03:37 +02:00
amacocian 3d84648af2 Update test dependencies (#757) 2024-06-11 15:03:37 +02:00
amacocian 38bb43bba3 Daybreak paths now fall back to root Daybreak folder (Closes #716) (#756)
* Daybreak paths now fall back to root Daybreak folder (Closes #716)

* Fix some more paths
2024-06-11 15:03:37 +02:00
amacocian cc00709016 Show skill icons in skill list menu (Closes #747) (#755)
* Show skill icons in skill list menu (Closes #747)

* Remove unused code
2024-06-11 15:03:37 +02:00
amacocian ee02b3b49a Download Gw.exe directly (Closes #753) (#754)
* Download Gw.exe directly (Closes #753)

* Downloader improvements
2024-06-11 15:03:37 +02:00
amacocian d1d6b7d757 Update GWCA module (#752) 2024-06-11 15:03:37 +02:00
amacocian 4e1c0c4f50 Save dump on crash (Closes #749) (#751) 2024-06-11 15:03:37 +02:00
amacocian 2a7e2c90fc Update dependencies (#750) 2024-06-11 15:03:37 +02:00
amacocian 0dc957a99d Release 0.9.9.44 2024-06-11 15:03:37 +02:00
amacocian f3f0aeb97e Update GWCA (#736) 2024-05-22 13:09:53 +02:00
amacocian d6dbe6f2cd Freeze layouts calculations on resize (Closes #734) (#735) 2024-05-22 13:09:53 +02:00
amacocian 79da1801bc GWCA Debug Module (#733) 2024-05-22 13:09:53 +02:00
amacocian 2b692b2d88 Update GWCA (#732) 2024-05-22 13:09:53 +02:00
amacocian a7a98f7288 Release 0.9.9.43 (#731) 2024-05-22 13:09:53 +02:00
amacocian 5d27d9c380 Update GWCA plugin (#729) 2024-05-10 23:09:23 +02:00
amacocian fb4185b541 Update httplib (#728) 2024-05-10 23:09:23 +02:00
amacocian d2d6e87e12 Add timeouts to GWCA modules (Closes #725) (#727) 2024-05-10 23:09:23 +02:00
amacocian 354cdda109 Release 0.9.9.42 (#726) 2024-05-10 23:09:23 +02:00
amacocian 83429e264a Update GWCA (#723) 2024-05-09 10:33:05 +02:00
amacocian ffdf374cdd Allow mods to cancel Guild Wars startup (Closes #717) (#721) 2024-05-09 10:33:05 +02:00
amacocian aed34608ee Improve GWCA plugin logging (Closes #718) (#720) 2024-05-09 10:33:05 +02:00
amacocian 18981e131d Release 0.9.9.41 (#719) 2024-05-09 10:33:05 +02:00
amacocian fe0a77d89d Fix automatic screen placer (Closes #708) (#714) 2024-05-06 00:27:48 +03:00
amacocian dbfd555f0d Improve detection of Guild Wars launching successfully (Closes #712) (#713) 2024-05-06 00:27:48 +03:00
amacocian 85d4ac3a29 Remove price checker (now incl. in Toolbox) (Closes #707) (#711) 2024-05-06 00:27:48 +03:00
amacocian dcb983d3de Update GWCA (#710) 2024-05-06 00:27:48 +03:00
amacocian ba1e4348ad Release 0.9.9.40 (#709) 2024-05-06 00:27:48 +03:00
amacocian 04bc7cffc6 Update GWCA (Closes #696) (#705) 2024-05-01 12:35:14 +03:00
amacocian 01b74a936b Rewrite GWCA module for better maintainability (#702)
* Use game thread enqueue method

* Remove manual memory handling

* Use game thread enqueue method

* Remove manual memory handling

* Setup module classes
2024-05-01 12:35:14 +03:00
dependabot[bot]amacociandependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
654b6bc10f Bump HtmlAgilityPack from 1.11.60 to 1.11.61 (#704)
Bumps [HtmlAgilityPack](https://github.com/zzzprojects/html-agility-pack) from 1.11.60 to 1.11.61.
- [Release notes](https://github.com/zzzprojects/html-agility-pack/releases)
- [Commits](https://github.com/zzzprojects/html-agility-pack/compare/v1.11.60...v1.11.61)

---
updated-dependencies:
- dependency-name: HtmlAgilityPack
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-01 12:35:14 +03:00
amacocian c9e6b9f626 Shortcut auto-place no longer removes arguments (Closes #695) (#701) 2024-05-01 12:35:14 +03:00
amacocian 554f1aea9b Fix extracted minimap not updating (Closes #698) (#700) 2024-05-01 12:35:14 +03:00
dependabot[bot]amacociandependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
6fb817855c Bump SharpCompress from 0.37.0 to 0.37.2 (#697)
Bumps [SharpCompress](https://github.com/adamhathcock/sharpcompress) from 0.37.0 to 0.37.2.
- [Release notes](https://github.com/adamhathcock/sharpcompress/releases)
- [Commits](https://github.com/adamhathcock/sharpcompress/compare/0.37.0...0.37.2)

---
updated-dependencies:
- dependency-name: SharpCompress
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-05-01 12:35:14 +03:00
amacocian b3f5fadfe3 Release 0.9.9.39 (#699) 2024-05-01 12:35:14 +03:00
DubbleClick 9275b7a7f8 simpler PreGameModule, test this 2024-04-28 23:14:58 +02:00
DubbleClick 2d06ff85b8 ignore .idea folder 2024-04-28 23:00:38 +02:00
amacocian 07d06313d9 Support for GuildWars launch arguments (Closes #691) (#693) 2024-04-27 13:46:53 +02:00
amacocian 546409130c Auto launch configuration (Closes #689) (#692) 2024-04-27 13:46:53 +02:00
amacocian 82436872f8 Launch argument support (Closes #689) (#690) 2024-04-27 13:46:53 +02:00
amacocian ad6f76af0c Event notification expiration set to 15s (Closes #686) (#688) 2024-04-27 13:46:53 +02:00
amacocian 8f0ad91a22 Bundle quote alerts (Closes #676) (#687) 2024-04-27 13:46:53 +02:00
amacocian 6a70c5b7cc Fix 'yearss' typo in Trade chat (Closes #677) (#685) 2024-04-27 13:46:53 +02:00
amacocian 5f5d67fdf2 Release 0.9.9.38 (#684) 2024-04-27 13:46:53 +02:00
dependabot[bot]andamacocian 150b41647a Bump SharpCompress from 0.36.0 to 0.37.0 (#675)
Bumps [SharpCompress](https://github.com/adamhathcock/sharpcompress) from 0.36.0 to 0.37.0.
- [Release notes](https://github.com/adamhathcock/sharpcompress/releases)
- [Commits](https://github.com/adamhathcock/sharpcompress/compare/0.36.0...0.37.0)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-26 20:48:21 +02:00
amacocian 66e52e7324 Remove redundant GWCA calls on non-visible components (#681) 2024-04-26 20:48:21 +02:00
amacocian 23328240a9 Fix launch button spamming GWCA (#680) 2024-04-26 20:48:21 +02:00
amacocian 3f06e9486d Setup release 0.9.9.37 (#678) 2024-04-26 20:48:21 +02:00
dependabot[bot]amacociandependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
52a8e912e9 Bump Microsoft.Web.WebView2 from 1.0.2420.47 to 1.0.2478.35 (#669)
Bumps Microsoft.Web.WebView2 from 1.0.2420.47 to 1.0.2478.35.

---
updated-dependencies:
- dependency-name: Microsoft.Web.WebView2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-04-23 14:59:34 +02:00
amacocian 641aa8250e Minimap player arrow (#673) 2024-04-23 14:59:34 +02:00
amacocian faa47f32c7 Minimap angle (#672) 2024-04-23 14:59:34 +02:00
amacocian e3dac780df Update GWCA (#671) Closes (#668) 2024-04-23 14:59:34 +02:00
amacocian dfc0f12150 Release 0.9.9.36 (#670) 2024-04-23 14:59:34 +02:00
amacocian 638fb38fa0 Fix exception when extracting maximized minimap (Closes #662) (#666) 2024-04-22 14:33:10 +02:00
amacocian 4d6a06ccdf Floodplains of Mahnkelon id (Closes #653) (#665) 2024-04-22 14:33:10 +02:00
amacocian 3228604876 Item modifiers improvements (#664)
* Improve modifiers check for items

* Update minor vigor
2024-04-22 14:33:10 +02:00
amacocian 44879924d6 Release 0.9.9.35 2024-04-22 14:33:10 +02:00
amacocian 6b7478f6ae Save minimap pinned state (Closes #655) (#659) 2024-04-18 19:24:19 +02:00
amacocian f54d95c1e7 Fix word highlighting edge cases (Closes #656) (#658) 2024-04-18 19:24:19 +02:00
amacocian 5315a45a98 Fix browser navigation (Closes #654) (#657) 2024-04-18 19:24:19 +02:00
amacocian 8575d970a3 Setup release 0.9.9.34 2024-04-18 19:24:19 +02:00
amacocian 5c611eca4f GWCA Module Bugfix (#651) 2024-04-16 18:41:44 +02:00
amacocian 71aa37b965 Added 558 id for sparkfly swamp (#650) 2024-04-16 18:41:44 +02:00
amacocian 0f1b1cc83d Release 0.9.9.33 2024-04-16 18:41:44 +02:00
amacocian 198c1e6eb3 Update Daybreak.GWCA to 0.9.9.32 2024-04-16 11:28:18 +02:00
amacocian e7c9111a1f Allow credentials to be backed up (Closes #525) (#648) 2024-04-16 11:28:18 +02:00
amacocian 1191e996db Update GWCA (#647) 2024-04-16 11:28:18 +02:00
amacocian 19de3c99f9 Release 0.9.9.23 2024-04-16 11:28:18 +02:00
amacocian d857b6dc26 Bugfixes in GWCA module (#645) 2024-04-15 21:56:37 +02:00
amacocian 68b5b79035 Release 0.9.9.31 2024-04-15 21:56:37 +02:00
amacocian 318032d998 Inventory component loading widget (#643) 2024-04-15 12:13:52 +02:00
amacocian 483860532f Update GWCA (#642) 2024-04-15 12:13:52 +02:00
amacocian 694dbe82a9 Race condition crashfix - Downgrade LiteDB dependency - Closes #640 (#641) 2024-04-15 12:13:52 +02:00
amacocian a936f24e32 Setup release branch 2024-04-15 12:13:52 +02:00
amacocian a2ec87ced2 Update GWCA module (#638) 2024-04-12 02:46:53 +02:00
amacocian 48955a7dd7 Setup GWCA whisper functionality (#636) 2024-04-12 02:46:53 +02:00
amacocian 9d7c6c29b0 Setup periodical price checker for inventory (#635) 2024-04-12 02:46:53 +02:00
amacocian 902d210dfd Fix pointer in GWCA plugin (#633) 2024-04-12 02:46:53 +02:00
amacocian 57867851a9 Release 0.9.9.29 2024-04-12 02:46:53 +02:00
amacocianandGitHub ca82cc92bf Release 0.9.9.28 (#632)
Update GWCA
2024-04-11 17:58:39 +00:00
amacocianandGitHub 569ce1e656 Release-0.9.9.27
Release 0.9.9.27
Changelog viewer
2024-04-11 19:28:36 +02:00
amacocian a96c6c3f66 Release 0.9.9.27
Implement changelog view (#629)
2024-04-11 19:19:15 +02:00
amacocian 28c3b2f8c1 Fix CD pipeline 2024-04-11 18:29:04 +02:00
amacocianandGitHub deeccd81b4 Release 0.9.9.26 (#628)
* Event Calendar (#625)

* Event calendar view

* Update GWCA (#626)

* Publish changelog (#627)

* Update dependencies
2024-04-11 16:26:22 +00:00
amacocianandGitHub 6a27245ae8 Release 0.9.9.25 (#618) 2024-04-02 16:59:21 +00:00
amacocianandGitHub 6f4063abb7 Release v0.9.9.24 (#617)
Fix price history functionality
Implement all runes
Update dependencies
2024-03-27 21:33:30 +00:00
amacocianandGitHub f307bcd665 Release 0.9.9.23 (#615)
* Create 0.9.9.23 release

* Update dependencies
2024-03-18 17:52:51 +00:00
amacocianandGitHub 02ca41ba6d Release 0.9.9.22 (#612)
* Fix Daybreak restart commands

* Option to disable dynamic backgrounds

* Improve game running detection
2024-03-04 15:33:00 +00:00
amacocianandGitHub a0ebc87b7c Release 0.9.9.21 (#609)
Fix updater packaging logic
2024-02-27 14:08:02 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
d21c55deb0 Bump Xotl/cool-github-releases from 1.1.8 to 1.1.10 (#608)
Bumps [Xotl/cool-github-releases](https://github.com/xotl/cool-github-releases) from 1.1.8 to 1.1.10.
- [Release notes](https://github.com/xotl/cool-github-releases/releases)
- [Commits](https://github.com/xotl/cool-github-releases/compare/v1.1.8...v1.1.10)

---
updated-dependencies:
- dependency-name: Xotl/cool-github-releases
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-27 12:53:07 +00:00
amacocianandGitHub 50a8131ec2 Update dependencies (#607)
Improve updater
2024-02-27 12:42:39 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
e70cfa3d99 Bump coverlet.collector from 6.0.0 to 6.0.1 (#596)
Bumps [coverlet.collector](https://github.com/coverlet-coverage/coverlet) from 6.0.0 to 6.0.1.
- [Release notes](https://github.com/coverlet-coverage/coverlet/releases)
- [Commits](https://github.com/coverlet-coverage/coverlet/compare/v6.0.0...v6.0.1)

---
updated-dependencies:
- dependency-name: coverlet.collector
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-24 20:46:19 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
4c0c45f1c7 Bump MSTest.TestFramework from 3.2.1 to 3.2.2 (#600)
Bumps [MSTest.TestFramework](https://github.com/microsoft/testfx) from 3.2.1 to 3.2.2.
- [Release notes](https://github.com/microsoft/testfx/releases)
- [Changelog](https://github.com/microsoft/testfx/blob/main/docs/Changelog.md)
- [Commits](https://github.com/microsoft/testfx/compare/v3.2.1...v3.2.2)

---
updated-dependencies:
- dependency-name: MSTest.TestFramework
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-24 20:32:37 +00:00
amacocianandGitHub a9e819a83a Release 0.9.9.19 (#602)
Disable GWCA component when Focus View is disabled
2024-02-24 20:20:11 +00:00
amacocianandGitHub 65830f9125 Release 0.9.9.18 (#595)
* Setup release 0.9.9.18

* Minimap transparency
Closes #594

* Toggle to display exploration percentage
Closes #593
2024-02-18 22:55:07 +01:00
amacocianandGitHub 3d9106addf Release 0.9.9.17 (#592)
* Setup release 0.9.9.17

* Save extracted minimap window position (#591)

Closes #590

* Add ability to pin minimap to screen
Closes #585

* Fix ObjectDisposedException
Closes #589
2024-02-18 16:04:52 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>amacocian
2863032d9a Bump MSTest.TestAdapter from 3.2.0 to 3.2.1 (#587)
Bumps [MSTest.TestAdapter](https://github.com/microsoft/testfx) from 3.2.0 to 3.2.1.
- [Release notes](https://github.com/microsoft/testfx/releases)
- [Changelog](https://github.com/microsoft/testfx/blob/main/docs/Changelog.md)
- [Commits](https://github.com/microsoft/testfx/compare/v.3.2.0...v3.2.1)

---
updated-dependencies:
- dependency-name: MSTest.TestAdapter
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Macocian Alexandru Victor <amacocian@yahoo.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Macocian Alexandru Victor <amacocian@yahoo.com>
2024-02-14 10:48:58 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
aada189b1b Bump MSTest.TestFramework from 3.2.0 to 3.2.1 (#588)
Bumps [MSTest.TestFramework](https://github.com/microsoft/testfx) from 3.2.0 to 3.2.1.
- [Release notes](https://github.com/microsoft/testfx/releases)
- [Changelog](https://github.com/microsoft/testfx/blob/main/docs/Changelog.md)
- [Commits](https://github.com/microsoft/testfx/compare/v.3.2.0...v3.2.1)

---
updated-dependencies:
- dependency-name: MSTest.TestFramework
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-14 11:40:09 +01:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
22ea4de66e Bump NSubstitute.Analyzers.CSharp from 1.0.16 to 1.0.17 (#586)
Bumps [NSubstitute.Analyzers.CSharp](https://github.com/nsubstitute/NSubstitute.Analyzers) from 1.0.16 to 1.0.17.
- [Changelog](https://github.com/nsubstitute/NSubstitute.Analyzers/blob/1.0.17/ReleaseNotes.md)
- [Commits](https://github.com/nsubstitute/NSubstitute.Analyzers/compare/1.0.16...1.0.17)

---
updated-dependencies:
- dependency-name: NSubstitute.Analyzers.CSharp
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-12 05:46:15 +01:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
9859617a74 Bump Microsoft.NET.Test.Sdk from 17.8.0 to 17.9.0 (#578)
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.8.0 to 17.9.0.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md)
- [Commits](https://github.com/microsoft/vstest/compare/v17.8.0...v17.9.0)

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-07 15:41:59 +01:00
amacocianandGitHub 0629c1929d Release 0.9.9.16 (#582)
* Setup release 0.9.9.16

* Copy buttons for build templates (#580)

* Extract minimap functionality (#581)

* Improve performance of RowAutoMargin functionality
2024-02-07 15:24:47 +01:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
6ec45396c3 Bump microsoft/setup-msbuild from 1.3.2 to 2.0.0 (#575)
Bumps [microsoft/setup-msbuild](https://github.com/microsoft/setup-msbuild) from 1.3.2 to 2.0.0.
- [Release notes](https://github.com/microsoft/setup-msbuild/releases)
- [Changelog](https://github.com/microsoft/setup-msbuild/blob/main/building-release.md)
- [Commits](https://github.com/microsoft/setup-msbuild/compare/v1.3.2...v2.0.0)

---
updated-dependencies:
- dependency-name: microsoft/setup-msbuild
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-05 10:23:57 +01:00
amacocianandGitHub b76a9b80fb Release 0.9.9.15 (#574)
* Setup release 0.9.9.15

* Export team build from focus view (#573)

Closes #573

* Fix load skill template
2024-02-04 19:30:22 +01:00
amacocianandGitHub f4bc58bbf7 Release 0.9.9.14 (#570)
* Team build support (#565)

* Setup support for team builds
Fix parser to load team builds
Fix bug in attribute loading
Adjust encoder to order and skip attributes for consistency

* Small buildtemplate binding fixes
Setup TeamBuildTemplateView

* Setup button to create team build

* Fix launch button (#566)

Closes #563

* Team build improvements (#568)

Closes #564

* Closes #562 (#569)

Closes #561

* Increment version
2024-02-04 14:11:01 +00:00
amacocianandGitHub 09fdbb6f95 Release 0.9.9.13 (#560) 2024-02-01 14:52:15 +00:00
amacocianandGitHub 8ee7ed23e4 Release 0.9.9.12 (#558)
* Release 0.9.9.12

* Move injection to injector executable (#554)

* Fix logview missing history (#556)

Closes #526

* Detect unresponsive Guild Wars instance (#557)

Closes #534
Closes #422
2024-01-31 22:02:14 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>amacocian
8d8a78cf88 Bump microsoft/setup-msbuild from 1.3.1 to 1.3.2 (#552)
Bumps [microsoft/setup-msbuild](https://github.com/microsoft/setup-msbuild) from 1.3.1 to 1.3.2.
- [Release notes](https://github.com/microsoft/setup-msbuild/releases)
- [Changelog](https://github.com/microsoft/setup-msbuild/blob/main/building-release.md)
- [Commits](https://github.com/microsoft/setup-msbuild/compare/v1.3.1...v1.3.2)

---
updated-dependencies:
- dependency-name: microsoft/setup-msbuild
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Macocian Alexandru Victor <amacocian@yahoo.com>
2024-01-29 17:06:36 +01:00
amacocianandGitHub f0652231cb Fix minimap mouse interaction (#553)
* Rework minimap renderer

* Fix dragging

* Fix mouse over detection
2024-01-29 15:50:32 +00:00
amacocianandGitHub d9aa760256 Release 0.9.9.10 (#550)
* Release 0.9.9.10
Option to rotate minimap with the camera
Fix launch button not disabling properly when launching
Remove minimap id overlay
Closes #549
Closes #533
Closes #532

* Increment version

* Increment Daybreak.GWCA version
2024-01-28 14:56:51 +00:00
amacocianandGitHub a65f375255 Release 0.9.9.9 (#548)
Closes #547
Closes #546
Closes #536
2024-01-27 19:34:47 +00:00
amacocianandGitHub 3ee58e2711 Release 0.9.9.8 (#545)
* Synchronize browser history

* Intercept mouse button navigation
Closes #535
Closes #544
2024-01-26 14:24:32 +01:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>amacocian
9b3b083aec Bump MSTest.TestAdapter from 3.1.1 to 3.2.0 (#542)
Bumps [MSTest.TestAdapter](https://github.com/microsoft/testfx) from 3.1.1 to 3.2.0.
- [Release notes](https://github.com/microsoft/testfx/releases)
- [Changelog](https://github.com/microsoft/testfx/blob/main/docs/Changelog.md)
- [Commits](https://github.com/microsoft/testfx/compare/v3.1.1...v.3.2.0)

---
updated-dependencies:
- dependency-name: MSTest.TestAdapter
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Macocian Alexandru Victor <amacocian@yahoo.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Macocian Alexandru Victor <amacocian@yahoo.com>
2024-01-26 13:09:38 +01:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
ecb9b8f172 Bump MSTest.TestFramework from 3.1.1 to 3.2.0 (#543)
Bumps [MSTest.TestFramework](https://github.com/microsoft/testfx) from 3.1.1 to 3.2.0.
- [Release notes](https://github.com/microsoft/testfx/releases)
- [Changelog](https://github.com/microsoft/testfx/blob/main/docs/Changelog.md)
- [Commits](https://github.com/microsoft/testfx/compare/v3.1.1...v.3.2.0)

---
updated-dependencies:
- dependency-name: MSTest.TestFramework
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-01-26 13:08:22 +01:00
amacocianandGitHub 5765c27240 Release 0.9.9.7 (#541)
* Introduce support for browser extensions

* Setup ublock origin

* Release 0.9.9.7 branch

* Automatically backup settings
Closes #539

* Compare settings with remote
2024-01-23 18:25:31 +00:00
amacocianandGitHub c53456112a Update GWCA (#538)
Fix inventory bug
2024-01-20 10:19:46 +00:00
amacocianandGitHub ccea21886e Release 0.9.9.5 (#531)
* Remove character name from credentials
Update vulnerable packages

* Update SharpCompress
2024-01-17 20:00:12 +00:00
amacocianandGitHub 37be8de5ac Update httplib (#529)
Fix missing data when player has no titles
Fix http requests stalling
2024-01-15 19:20:55 +00:00
amacocianandGitHub 107e43a15f Update GWCA (#528) 2024-01-15 13:34:41 +00:00
amacocianandGitHub 17b3ed34db Disable wintersday mode (#527) 2024-01-09 14:06:05 +02:00
amacocianandGitHub cce9cd34af Update README.md (#524)
Signed-off-by: Macocian Alexandru Victor <amacocian@yahoo.com>
2023-12-22 07:58:23 +02:00
amacocianandGitHub 6a80f8ee5d Escape parameters passed to Guild Wars on launch (#522) 2023-12-20 14:54:34 +00:00
amacocianandGitHub edb7f0d0bd Beta release 0.9 (#521)
Closes #453
2023-12-20 00:27:29 +00:00
amacocianandGitHub 8e69375338 Fix application updater start message (#520)
Closes #519
2023-12-19 23:59:39 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>amacocian
d24ae98fb0 Bump github/codeql-action from 2 to 3 (#516)
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2 to 3.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/v2...v3)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Macocian Alexandru Victor <amacocian@yahoo.com>
2023-12-19 23:22:27 +00:00
amacocianandGitHub 111b3ea632 Setup setting synchronization functionality (#518)
* Setup setting synchronization functionality
Update dependencies
Closes #515

* Disable mainwindow periodic check
2023-12-19 23:05:53 +00:00
amacocian cc1e759972 Improve updater responsiveness
Closes #514
2023-12-15 16:18:03 +01:00
amacocianandGitHub ad0527ed73 Notifications improvements (#513)
Add checkbox for unopened notifications
Added sort options for notifications
Closes #511
Closes #510
2023-12-15 15:13:48 +00:00
amacocianandGitHub 8ffbb918ea Add frequency checking option for trader quote alerts (#512)
Hide sell trade quotes since they don't populate
Closes #509
Closes #508
2023-12-15 13:08:51 +00:00
amacocianandGitHub c27a0dba65 Setup alerts for quotes (#507) 2023-12-12 15:22:40 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
ad8305c66d Bump actions/setup-dotnet from 3 to 4 (#505)
Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet) from 3 to 4.
- [Release notes](https://github.com/actions/setup-dotnet/releases)
- [Commits](https://github.com/actions/setup-dotnet/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/setup-dotnet
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-12-12 12:41:35 +01:00
amacocianandGitHub 29fe12f094 Revert injector extraction (#504)
* Revert "Extract injector to its own process (#503)"

This reverts commit 9dbe4c5eaf.

* Revert injector extraction
2023-12-04 14:54:34 +01:00
amacocianandGitHub 9dbe4c5eaf Extract injector to its own process (#503) 2023-12-04 14:12:18 +01:00
amacocianandGitHub 1e9aca3807 Onboard SharpNav for pathfinding (#502) 2023-11-29 23:05:41 +00:00
amacocianandGitHub 895da23f7d Re-enable beta update by default (#500)
Extra pictures
2023-11-23 18:39:44 +00:00
amacocianandGitHub f788a10879 Implement file version checking for updater (#499)
* Implement file version checking for updater

* Increment version
2023-11-23 17:17:58 +00:00
amacocianandGitHub 9fe4be0467 Remove privilege mode for updater (#497) 2023-11-22 20:51:54 +00:00
amacocianandGitHub b1a7d3a111 Improve update procedure (#496)
* Improve update procedure

* Change release procedure

* Fix gh release

* Fix release tag

* Change release structure to support folders

* Revert zip file changes to make them backwards compatible

* Change path

* Make launcher not contain the entire dependencies

* Add downtime after API rate limit

* Add rate limit checking before create release

* Enumerate through rates

* Adjust rate limit call

* Change to create release as draft

* Add update logic based on azure blobs

* Fix publish

* Create zip

* Disable CD pipeline for prs

* Increment version

* Fix tests
2023-11-22 21:13:01 +01:00
amacocianandGitHub 8b9fdaaa30 Release v152 (#493)
Improve LaunchView responsiveness
Show current uMod version
Make services and models internal
Closes #491
Closes #490
Closes #381
2023-11-21 16:25:32 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
60d5947535 Bump SharpCompress from 0.34.1 to 0.34.2 (#489)
Bumps [SharpCompress](https://github.com/adamhathcock/sharpcompress) from 0.34.1 to 0.34.2.
- [Release notes](https://github.com/adamhathcock/sharpcompress/releases)
- [Commits](https://github.com/adamhathcock/sharpcompress/compare/0.34.1...0.34.2)

---
updated-dependencies:
- dependency-name: SharpCompress
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-21 15:25:31 +01:00
amacocianandGitHub 0ba0e64a2a Small fixes (#488)
Fix copy folder picker
Fix metrics
Closes #487
Closes #474
2023-11-19 00:17:26 +00:00
amacocianandGitHub e1dfd1f0d0 Update to .net8.0 (#486)
Fix uMod installation steps
ReShade monitor config changes
2023-11-18 23:40:09 +00:00
amacocianandGitHub cd2a529381 Catch exceptions on startup (#485)
Extend process injection timeout (mainly due to uMod)
2023-11-17 15:50:08 +00:00
amacocianandGitHub 6ba8dcac49 Upgrade GWCA (#480) 2023-11-14 13:09:32 +00:00
amacocianandGitHub f2e76b5459 Show winter related background for Wintersday (#479)
* Show winter related background for Wintersday
Closes #449
Contributes to #453

* Increment version
2023-11-13 22:40:41 +00:00
amacocianandGitHub cfbf6ed021 Update toolbox and uMod links to gwdevhub (#477) 2023-11-12 15:30:06 +00:00
amacocianandGitHub a372eb5125 Replace uMod with gMod (#476) 2023-11-10 17:09:54 +00:00
amacocianandGitHub 76b89ca0e8 Make Daybreak create a modlist.txt for uMod (#475) 2023-11-10 11:06:30 +00:00
amacocianandGitHub 2c1721d52c Bugfixes (#473)
Fix NRE in minimap
Add a fallback routine to figure out if an elevated guildwars executable is running
2023-11-10 00:11:24 +00:00
amacocianandGitHub 324a77a625 Update UMod startup action (#472)
Minor mod fixes
2023-11-09 22:09:47 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
88e59b8ec9 Bump Microsoft.NET.Test.Sdk from 17.8.0-release-23468-02 to 17.8.0 (#471)
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.8.0-release-23468-02 to 17.8.0.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md)
- [Commits](https://github.com/microsoft/vstest/compare/v17.8.0-release-23468-02...v17.8.0)

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-11-09 23:00:54 +01:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>amacocian
df71a17d9f Bump Microsoft.Web.WebView2 from 1.0.2088.41 to 1.0.2151.40 (#469)
* Bump Microsoft.Web.WebView2 from 1.0.2088.41 to 1.0.2151.40

Bumps Microsoft.Web.WebView2 from 1.0.2088.41 to 1.0.2151.40.

---
updated-dependencies:
- dependency-name: Microsoft.Web.WebView2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Fix version

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Alex Macocian <amacocian@yahoo.com>
2023-11-08 19:08:20 +00:00
amacocianandGitHub 8451f53e19 UMod bugfixes (#470) 2023-11-08 18:55:07 +00:00
amacocianandGitHub e795af5c11 Fix 7Zip Extractor (#467)
* Fix 7Zip Extractor
Closes #466

* Increment version
2023-11-05 21:27:37 +00:00
amacocianandGitHub efa3c5175c Add DirectSong support (#465)
Various small fixes
Closes #464
2023-11-05 20:31:30 +00:00
amacocianandGitHub 32efe42a61 Minor fixes (#463)
Fix build loading from GWCA
Introduce persistence toggle for logging to reduce disk usage
Improve performance of memory usage and processor usage counters
Add disk usage counters
Closes #462
Closes #461
2023-11-04 19:30:27 +00:00
amacocianandGitHub 97d2d09cdc Fix toolbox and gwca integration (#460)
Closes #458
2023-11-03 20:05:52 +00:00
amacocianandGitHub ed90d567a4 Wintersday preparation (#457)
Snowfall effect
Setup OnlinePictureClient to support more online sources
Contributes to #453
2023-11-02 17:04:18 +00:00
amacocianandGitHub 51d6fb0f42 Fix vanquishing API (#448)
Pass Health/Energy from GWCA
Fix for enemy primary professions
Fix for LiveCharts2 memory leak
Update GWCA

Closes #447
Closes #446
Closes #445
Closes #444
Closes #442
2023-10-29 16:59:05 +00:00
amacocianandGitHub c10525708c Expose APIs for entity and item names (#443)
Rework logic to reuse functions in Utils.h
Rely on GameState for entity positions and state, greatly improves performance
2023-10-29 00:35:26 +00:00
amacocianandGitHub 0a69d795aa Button to load plugin (#438)
Detect broken GuildWars
Closes #437
Closes #407
2023-10-28 17:36:37 +00:00
amacocianandGitHub 3b1d6831a5 Fix quest metadata position (#436)
* Fix quest metadata position
Closes #435

* Increment version
2023-10-28 14:47:07 +02:00
amacocianandGitHub b4c1dbcddb Deprecate memory reader (#434)
* Deprecate memory reader
Switch completely to GWCA plugin
Fix InventoryModule item ids
Fix InventoryModule modifiers
FIx BloogumClient image retrieval

* Increment version
2023-10-28 12:28:26 +00:00
amacocianandGitHub db5d62d7c0 Name module improvements (#431)
Add waiting logic for names
Remove debouncing logic
Add ability to search wiki by npc name
Update GWCA
2023-10-28 09:51:43 +00:00
amacocianandGitHub ed5ccf38c6 GWCA follow-up (#430)
* Improvements to GWCA integration
Optimize GWCA calls
Add API to get entity names
Fix memory violations in GWCA
Closes #429
Closes #428

* Increment version
2023-10-27 21:33:44 +00:00
amacocianandGitHub 7671e0c04c GWCA Integration (#426)
* GWCA integration
GWCAMemoryReader partial implementation

* Complete Daybreak.GWCA implementation
Fix metrics view
Upgrade dependencies

* Update version

* Add solution dir property

* Another try

* Fix version check

* Fix codeql pipeline

* Codeql fixes

* Fetch submodules

* Final codeql change
2023-10-26 23:18:08 +02:00
amacocianandGitHub f3b8221b29 Improve Guild Wars launcher process (#423)
Added timeouts for mod startup
Added detection logic for uMod breaking after GuildWars update

Closes #415
2023-10-13 11:44:47 +00:00
amacocianandGitHub 8fdc9a67c0 Setup launch configurations (#420)
Adjust Daybreak logic to support loading multiple configurations
Closes #419
Closes #410
2023-10-11 13:29:58 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
bb2e739876 Bump Microsoft.NET.Test.Sdk (#416)
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.8.0-preview-23424-02 to 17.8.0-release-23468-02.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md)
- [Commits](https://github.com/microsoft/vstest/compare/v17.8.0-preview-23424-02...v17.8.0-release-23468-02)

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-05 16:47:47 +02:00
amacocianandGitHub 852cbff5f3 Integrate with ReShade (#417)
Change build to x86 to support new process injection
Add an intermediary step for mods when launching Guild Wars
2023-10-05 12:26:54 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>amacocian
6e1c111876 Bump HtmlAgilityPack from 1.11.53 to 1.11.54 (#414)
* Bump HtmlAgilityPack from 1.11.53 to 1.11.54

Bumps [HtmlAgilityPack](https://github.com/zzzprojects/html-agility-pack) from 1.11.53 to 1.11.54.
- [Release notes](https://github.com/zzzprojects/html-agility-pack/releases)
- [Commits](https://github.com/zzzprojects/html-agility-pack/compare/v1.11.53...v1.11.54)

---
updated-dependencies:
- dependency-name: HtmlAgilityPack
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Increment version

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Alexandru Macocian <amacocian@yahoo.com>
2023-10-04 10:51:24 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
9f60839e40 Bump LiveChartsCore.SkiaSharpView.WPF from 2.0.0-rc1 to 2.0.0-rc1.2 (#411)
Bumps [LiveChartsCore.SkiaSharpView.WPF](https://github.com/beto-rodriguez/LiveCharts2) from 2.0.0-rc1 to 2.0.0-rc1.2.
- [Release notes](https://github.com/beto-rodriguez/LiveCharts2/releases)
- [Commits](https://github.com/beto-rodriguez/LiveCharts2/commits)

---
updated-dependencies:
- dependency-name: LiveChartsCore.SkiaSharpView.WPF
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-26 18:26:03 +02:00
amacocianandGitHub dd37db18b5 Theming fixes and improvements (#413)
Fixes issue with LightMode initialization
Syncs Daybreak theme with Windows theme
Closes #412
Closes #406
2023-09-26 16:09:38 +00:00
amacocianandGitHub 793d60f7b5 Add tooltips for buttons (#409)
Closes #379
2023-09-25 14:22:52 +00:00
amacocianandGitHub 08674cd7a6 UMod improvements (#405)
Allow reordering of uMod load order
Allow uMod to load zip files
Fix auto-enable description

Closes #388
Closes #386
Closes #385
2023-09-24 19:57:12 +00:00
amacocianandGitHub dca3e39a6d Force background image (#404)
* Force background image
Closes #403

* Increment version
2023-09-24 20:56:46 +02:00
amacocianandGitHub 8a1033d4b6 Fix for missing options on fresh install (#402)
Closes #401
2023-09-24 20:34:41 +02:00
amacocianandGitHub e4ebe558d7 Use Reloaded.Injector to avoid cross WoW64 boundary issues (#400)
Closes #399
2023-09-23 01:40:40 +00:00
amacocianandGitHub 70728cc5ed Delay toolbox startup (#398)
Closes #397
2023-09-23 01:54:20 +02:00
amacocianandGitHub b49a0a5ff4 Update dependencies (#396) 2023-09-22 23:43:07 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
b48d959ffb Bump FluentAssertions from 6.11.0 to 6.12.0 (#394)
Bumps [FluentAssertions](https://github.com/fluentassertions/fluentassertions) from 6.11.0 to 6.12.0.
- [Release notes](https://github.com/fluentassertions/fluentassertions/releases)
- [Changelog](https://github.com/fluentassertions/fluentassertions/blob/develop/AcceptApiChanges.ps1)
- [Commits](https://github.com/fluentassertions/fluentassertions/compare/6.11.0...6.12.0)

---
updated-dependencies:
- dependency-name: FluentAssertions
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-23 01:23:05 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
b8e1ad89af Bump Microsoft.NET.Test.Sdk (#391)
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.8.0-preview-23371-04 to 17.8.0-preview-23424-02.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Changelog](https://github.com/microsoft/vstest/blob/main/docs/releases.md)
- [Commits](https://github.com/microsoft/vstest/compare/v17.8.0-preview-23371-04...v17.8.0-preview-23424-02)

---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-23 01:22:46 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
b2bfbfcd86 Bump actions/checkout from 3 to 4 (#390)
Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v3...v4)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-23 01:22:17 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
062e28a6d2 Bump NSubstitute from 5.0.0 to 5.1.0 (#395)
Bumps NSubstitute from 5.0.0 to 5.1.0.

---
updated-dependencies:
- dependency-name: NSubstitute
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-23 01:21:42 +02:00
amacocian dc0f833291 Re-create dependabot.yaml 2023-09-23 01:20:22 +02:00
amacocian e598237916 Remove dependabot.yaml 2023-09-23 01:19:56 +02:00
amacocianandGitHub 6b96d3d9e9 Inject toolbox dll into GuildWars (#389)
Closes #384
2023-09-22 23:11:36 +00:00
amacocianandGitHub 1dbb610846 Code cleanup (#387)
Closes #382
2023-09-22 16:10:07 +00:00
amacocianandGitHub 5c649b0c15 Integrate with uMod dll (#383) 2023-09-22 15:35:05 +00:00
amacocianandGitHub 527ab041d9 Fixes for the Background provider (#377)
Closes #376
2023-09-19 16:21:23 +00:00
amacocianandGitHub ff94e90259 Toggle background effects (#375) 2023-09-19 08:20:52 +00:00
amacocianandGitHub 51efbcce1e Update README.md (#374)
Signed-off-by: Macocian Alexandru Victor <amacocian@yahoo.com>
2023-09-19 09:28:37 +02:00
amacocianandGitHub 87b2345105 Daybreak Splash Screen (#373)
Closes #369
2023-09-16 12:57:07 +00:00
amacocianandGitHub 5022d33ca9 Ask for restart only when detecting change in plugins (#372)
Closes #371
2023-09-15 23:21:01 +00:00
amacocianandGitHub 141f949a63 Plugin support (#370)
Adds a plugin management view
Implements a basic plugin as an example
Closes #361
2023-09-15 19:22:52 +00:00
amacocianandGitHub 3913c71fd8 Release v107 (#368)
Handle browser component missing in FocusView
Fix credit text when failing to load image
Closes #298
Closes #366
2023-09-12 13:57:12 +00:00
amacocianandGitHub 5706652c40 Pathing drawing fix (#365)
Closes #364
2023-09-11 15:08:52 +00:00
amacocianandGitHub 768b6b20f5 Pathfinding improvements (#360)
Use optimization passes to improve final paths
2023-09-11 14:04:09 +00:00
amacocianandGitHub 7066b7dbb6 GW2 style backgrounds (#359)
* Guildwars 2 styled background
Fix Screenshot provider
Closes #358

* Remove unnecessary code
2023-09-11 10:14:50 +00:00
amacocianandGitHub 17e01fc7b9 Disable launch button when loadin guildwars (#357)
Verify window placement on startup
Update as notification
Closes #349
Closes #347
Closes #346
2023-09-09 15:31:13 +00:00
amacocianandGitHub ee9fcf38b7 Release v102 (#355)
Restrict maximum notification size
Browser detects builds in downloaded files
BuildTemplate has a button to navigate to the build source
Closes #354
Closes #353
Closes #352
2023-09-08 10:32:47 +00:00
amacocianandGitHub 5abb24bdd4 Append source url for builds loaded through the browser (#351)
Closes #350
2023-09-07 23:48:13 +00:00
amacocianandGitHub 53f17d3f22 Display event remaining time (#348)
* Event notifications display remaining time
Closes #344

* Increment version
2023-09-03 20:06:41 +00:00
amacocianandGitHub b728c38dc1 Map fixes & Npcs (#345) 2023-09-01 12:33:52 +00:00
amacocianandGitHub 5e57b6ecd0 Notification fixes (#343)
* Notification fixes
Closes #342

* Update version
2023-08-31 22:26:49 +00:00
amacocianandGitHub e9ffcdf7c3 Add search capability to logs (#341)
Closes #340
2023-08-22 13:37:18 +00:00
amacocian 118657de7c Allow CD pipeline to be run manually 2023-08-09 23:57:14 +02:00
amacocian 34c332504b Fix cd pipeline 2023-08-09 23:54:45 +02:00
amacocianandGitHub d7a29d68a1 Release v96 (#338)
Add support for non-persistent notifications
LogsView message limit
Tradechat exponential backoff
Possibility to revert to normal mode

Closes #335
Closes #322
Closes #337
2023-08-09 20:56:24 +00:00
amacocianandGitHub eefa02837d Replace Moq with NSubstitute (#336)
* Replace Moq with NSubstitute

* CI fixes
Pin .net 7.0.9 in CI
Update test dependencies

* CI fixes
2023-08-09 15:23:50 +02:00
amacocianandGitHub 5b2812fa61 Release 95 (#334)
Fix mods launching regardless of status
LogsView improvements
NotificationsView improvements
Decrease frequency of ConnectivityStatus
Guildwars array validation
Chromium build template trim selection
Build template viewer improve skill dropdown
Update dependencies

Closes #333
Closes #332
Closes #318
Closes #319
2023-08-08 15:17:16 +00:00
amacocianandGitHub e3ddfb88c1 Add ETA to update view (#331)
Closes #205
2023-08-07 13:14:52 +00:00
amacocianandGitHub 664d94aeaa PreGameContext read implementation (#328)
Fixes for memory scanner
Closes #327
Closes #326
2023-08-07 11:02:36 +00:00
amacocianandGitHub e2baf63099 Events notifications (#325)
Closes #324
2023-08-06 22:29:21 +00:00
amacocianandGitHub c1b7000139 Connection data (#317) 2023-07-24 09:44:43 +00:00
amacocianandGitHub 6e8333d76f CD fixes 2 (#314)
* CD fixes 2

* Increment version
2023-07-19 13:16:12 +03:00
amacocianandGitHub c67eddc9d4 Re-enable CD pipeline (#313) 2023-07-19 10:09:21 +00:00
amacocianandGitHub 292cf6fd94 Screen placer fixes (#312)
* Screen placer fixes
Make screen placer as a mod
Validate login data

* Remove restrictions on CD pipeline
2023-07-19 12:43:15 +03:00
amacocianandGitHub 69038bca43 Revert "Screen placer fixes (#310)" (#311)
This reverts commit f05d15ce36.
2023-07-19 12:25:36 +03:00
amacocianandGitHub f05d15ce36 Screen placer fixes (#310)
Make screen placer as a mod
Validate login data
2023-07-19 12:08:02 +03:00
amacocianandGitHub 98cb349d67 Screen placer fixes (#310)
Make screen placer as a mod
Validate login data
2023-07-19 09:06:57 +00:00
amacocianandGitHub a4314ee4d5 Permission fixes for DSOAL (#309)
* Permission fixes for DSOAL
Registry service fixes

* Show notification on fix
2023-07-16 18:08:03 +00:00
amacocianandGitHub 96097bd25a Unify UI margins (#308) 2023-07-16 16:52:20 +00:00
amacocianandGitHub 14029e6af2 Cloudflare iaum mitigation (#307)
* Cloudflare iaum mitigation
Closes #305

* Increment version
2023-07-15 11:05:27 +00:00
amacocianandGitHub 365777141d Daybreak v84 (#306)
DSOAL installation requiring admin mode
DOSAL installation overwriting existing symbollic link
DSOAL check symbollic link before launching
MenuList can be scrollable
RegisterService implementation
Notifications show date of notification
Performance improvements for picture loading
Allow metric streaming to MetricsView
Handle cloudflare blocking responses
Closes #304
Closes #303
Closes #301
Closes #300
Mitigates #305
2023-07-15 10:32:30 +00:00
amacocianandGitHub aaa5da8d9b More nightfall endgame npcs (#299) 2023-06-30 20:00:52 +00:00
amacocianandGitHub b898ab5679 Fix cache size calculation (#297) 2023-06-29 18:32:18 +00:00
amacocianandGitHub b896fa5cc7 Bugfix for image memory cache (#296)
Improved memory usage monitor
2023-06-29 16:21:19 +00:00
1004 changed files with 34624 additions and 14093 deletions
+77 -17
View File
@@ -12,6 +12,7 @@ on:
paths:
- "Daybreak/**"
- "Daybreak.Installer/**"
workflow_dispatch:
jobs:
@@ -19,7 +20,7 @@ jobs:
strategy:
matrix:
targetplatform: [x64]
targetplatform: [x86]
runs-on: windows-latest
@@ -32,7 +33,7 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0
@@ -45,20 +46,18 @@ jobs:
run: |
$changeLog = git log --no-merges --pretty="%h - %s (%an)<br />" ${{ env.LatestReleaseTag }}..HEAD
echo "::set-env name=Changelog::$changeLog"
mkdir Publish
echo $changeLog > .\Publish\changelog.txt
env:
LatestReleaseTag: ${{steps.getLatestTag.outputs.tag}}
- name: Print changelog
run: |
echo "${{ env.Changelog }}"
- name: Install .NET Core
uses: actions/setup-dotnet@v3
uses: actions/setup-dotnet@v4
with:
dotnet-version: '7.x'
dotnet-version: '9.x'
- name: Setup MSBuild.exe
uses: microsoft/setup-msbuild@v1.3.1
uses: microsoft/setup-msbuild@v2.0.0
- name: Setup project secrets
run: |
@@ -66,12 +65,12 @@ jobs:
dotnet user-secrets --project Daybreak\Daybreak.csproj set AadTenantId "${{ secrets.AadTenantId }}"
- name: Restore project
run: msbuild $env:Solution_Path /t:Restore /p:Configuration=$env:Configuration /p:RuntimeIdentifier=$env:RuntimeIdentifier
run: msbuild $env:Solution_Path /t:Restore /p:Configuration=$env:Configuration /p:RuntimeIdentifier=$env:RuntimeIdentifier --property:SolutionDir=$GITHUB_WORKSPACE
env:
RuntimeIdentifier: win-${{ matrix.targetplatform }}
- name: Build Daybreak project
run: dotnet build Daybreak -c $env:Configuration
run: dotnet build Daybreak -c $env:Configuration --property:SolutionDir=$env:GITHUB_WORKSPACE
- name: Set version variable
run: |
@@ -79,12 +78,22 @@ jobs:
echo "::set-env name=Version::$version"
- name: Create publish launcher files
run: dotnet publish .\Daybreak\Daybreak.csproj -c $env:Configuration -r $env:RuntimeIdentifier -p:PublishReadyToRun=true -p:PublishSingleFile=true --self-contained true -o .\Publish
run: dotnet publish .\Daybreak\Daybreak.csproj -c $env:Configuration -r $env:RuntimeIdentifier --property:SolutionDir=$env:GITHUB_WORKSPACE -p:PublishReadyToRun=true -p:PublishSingleFile=false --self-contained true -o .\Publish
env:
RuntimeIdentifier: win-${{ matrix.targetplatform }}
- name: Create publish installer files
run: dotnet publish .\Daybreak.Installer\Daybreak.Installer.csproj -c $env:Configuration -r $env:RuntimeIdentifier -p:PublishReadyToRun=true -p:PublishSingleFile=true --self-contained true -o .\Publish
run: dotnet publish .\Daybreak.Installer\Daybreak.Installer.csproj -c $env:Configuration -r $env:RuntimeIdentifier --property:SolutionDir=$env:GITHUB_WORKSPACE -p:PublishReadyToRun=true -p:PublishSingleFile=true --self-contained true -o .\Publish
env:
RuntimeIdentifier: win-${{ matrix.targetplatform }}
- name: Create publish extractor files
run: dotnet publish .\Daybreak.7ZipExtractor\Daybreak.7ZipExtractor.csproj -c $env:Configuration -r $env:RuntimeIdentifier --property:SolutionDir=$env:GITHUB_WORKSPACE -p:PublishReadyToRun=true -p:PublishSingleFile=false --self-contained true -o .\Publish
env:
RuntimeIdentifier: win-${{ matrix.targetplatform }}
- name: Create publish API files
run: dotnet publish .\Daybreak.API\Daybreak.API.csproj -c $env:Configuration -r $env:RuntimeIdentifier --property:SolutionDir=$env:GITHUB_WORKSPACE -p:PublishSingleFile=false --self-contained true -o .\Publish
env:
RuntimeIdentifier: win-${{ matrix.targetplatform }}
@@ -94,16 +103,67 @@ jobs:
.\Scripts\BuildRelease.ps1 -version $env:Version
shell: pwsh
- name: Publish release
uses: Xotl/cool-github-releases@v1.1.8
- name: Submit virustotal scan
shell: pwsh
run: |
cd Publish
$apiKey = "${{ secrets.VIRUSTOTAL_APIKEY }}"
$archiveName = "daybreakv${{ env.Version }}.zip"
$uploadUrlResponse = curl https://www.virustotal.com/api/v3/files/upload_url -H x-apikey:"$apiKey"
$uploadUrlResponse
$uploadUrlJson = $uploadUrlResponse | ConvertFrom-Json
$uploadUrl = $uploadUrlJson.data
$uploadResponse = curl --request POST --header x-apikey:"$apiKey" --header 'content-type: multipart/form-data' --form file="@$archiveName" --url $uploadUrl
$uploadResponse
$uploadResponseJson = $uploadResponse | ConvertFrom-Json
$resultsUrl = "https://www.virustotal.com/api/v3/analyses/$($uploadResponseJson.data.id)"
$resultsUrl
# Poll the results until the status is "completed"
$status = ""
while ($status -ne "completed") {
Start-Sleep -Seconds 10 # Wait for 10 seconds between checks
$results = curl --header x-apikey:"$apiKey" --url $resultsUrl
$results
$resultsJson = $results | ConvertFrom-Json
$status = $resultsJson.data.attributes.status
Write-Host "Current status: $status"
}
$resultsJson.data.attributes.results | ConvertTo-Json | Out-File -FilePath "VirusTotal.Results.json" -Encoding UTF8
$resultsJson.data.attributes.stats | ConvertTo-Json | Out-File -FilePath "VirusTotal.Stats.json" -Encoding UTF8
$stats = $resultsJson.data.attributes.stats
echo "::set-env name=VirusTotalStats::$stats"
- name: Publish blob files
run: |
Write-Host $env
.\Scripts\PushFilesToBlobStorage.ps1 -version $env:Version -sourcePath .\Publish\ -connectionString "${{ secrets.BLOBSTORAGE_CONNECTIONSTRING }}"
shell: pwsh
- name: Create release draft
uses: Xotl/cool-github-releases@v1.1.10
with:
mode: update
tag_name: v${{ env.Version }}
release_name: Daybreak v${{ env.Version }}
assets: .\Publish\daybreakv${{ env.Version }}.zip
assets: .\Publish\daybreakv${{ env.Version }}.zip;.\Publish\VirusTotal.Results.json;.\Publish\VirusTotal.Stats.json
github_token: ${{ env.GITHUB_TOKEN }}
replace_assets: true
body_mrkdwn: ${{ env.Changelog }}
body_mrkdwn: |
${{ env.Changelog }}
** VirustTotal Stats: **
```
${{ env.VirusTotalStats }}
```
isDraft: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Publish release
run: |
gh release edit v${{ env.Version }} --draft=false
shell: powershell
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+9 -9
View File
@@ -19,35 +19,35 @@ jobs:
strategy:
matrix:
targetplatform: [x64]
targetplatform: [x86]
runs-on: windows-latest
env:
Solution_Path: Daybreak.sln
Test_Project_Path: Daybreak.Tests\Daybreak.Tests.csproj
Wpf_Project_Path: Daybreak\Daybreal.csproj
Wpf_Project_Path: Daybreak\Daybreak.csproj
Actions_Allow_Unsecure_Commands: true
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install .NET Core
uses: actions/setup-dotnet@v3
uses: actions/setup-dotnet@v4
with:
dotnet-version: '7.x'
dotnet-version: '9.x'
- name: Setup MSBuild.exe
uses: microsoft/setup-msbuild@v1.3.1
uses: microsoft/setup-msbuild@v2.0.0
- name: Execute Unit Tests
run: dotnet test $env:Test_Project_Path
run: dotnet test $env:Test_Project_Path --property:SolutionDir=$env:GITHUB_WORKSPACE -p:ParallelizeTestCollections=false
- name: Restore the Wpf application to populate the obj folder
run: msbuild $env:Solution_Path /t:Restore /p:Configuration=$env:Configuration /p:RuntimeIdentifier=$env:RuntimeIdentifier
run: msbuild $env:Solution_Path /t:Restore /p:Configuration=$env:Configuration /p:RuntimeIdentifier=$env:RuntimeIdentifier --property:SolutionDir=$env:GITHUB_WORKSPACE
env:
Configuration: Debug
RuntimeIdentifier: win-${{ matrix.targetplatform }}
+20 -8
View File
@@ -36,13 +36,22 @@ jobs:
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
env:
Configuration: Release
Solution_Path: Daybreak.sln
Test_Project_Path: Daybreak.Tests\Daybreak.Tests.csproj
Wpf_Project_Path: Daybreak\Daybreak.csproj
Actions_Allow_Unsecure_Commands: true
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -57,12 +66,12 @@ jobs:
# If this step fails, then you should remove it and run the build manually (see below)
- name: Install .NET Core
uses: actions/setup-dotnet@v3
uses: actions/setup-dotnet@v4
with:
dotnet-version: '6.x'
dotnet-version: '9.x'
- name: Autobuild
uses: github/codeql-action/autobuild@v2
#- name: Autobuild
# uses: github/codeql-action/autobuild@v2
# ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
@@ -74,5 +83,8 @@ jobs:
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
- name: Build Daybreak project
run: dotnet build Daybreak -c $env:Configuration --property:SolutionDir=$env:GITHUB_WORKSPACE
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
uses: github/codeql-action/analyze@v3
+9 -4
View File
@@ -14,7 +14,7 @@ jobs:
strategy:
matrix:
targetplatform: [x64]
targetplatform: [x86]
runs-on: windows-latest
@@ -25,16 +25,21 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install .NET Core
uses: actions/setup-dotnet@v4
with:
dotnet-version: '9.x'
- name: Get Latest Tag
id: getLatestTag
uses: WyriHaximus/github-action-get-previous-tag@v1
- name: Build Daybreak project
run: dotnet build Daybreak -c $env:Configuration
run: dotnet build Daybreak -c $env:Configuration --property:SolutionDir=$env:GITHUB_WORKSPACE
- name: Set version variable
run: |
+4 -1
View File
@@ -28,6 +28,7 @@ x86/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
build/
[Bb]in/
[Oo]bj/
[Oo]ut/
@@ -361,4 +362,6 @@ MigrationBackup/
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
FodyWeavers.xsd
.idea
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<RootNamespace>Daybreak._7ZipExtractor</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="SharpCompress" Version="0.39.0" />
</ItemGroup>
</Project>
+42
View File
@@ -0,0 +1,42 @@
/*
* Extractor is in a different executable because of memory limitations. Daybreak needs to be compiled for x86 and as such has a memory limit of 2GB.
* 7Zip algorithm may require more than 2GB memory to unpack large zip files.
* As such, Daybreak.7ZipExtractor is x64.
*/
using SharpCompress.Archives;
if (args.Length != 2)
{
return -1;
}
var archivePath = args[0];
var destinationDirectory = args[1];
using var fileStream = new FileStream(archivePath, FileMode.Open);
using var archive = ArchiveFactory.Open(fileStream);
var progress = 0d;
var count = archive.Entries.Count();
var reader = archive.ExtractAllEntries();
while (reader.MoveToNextEntry())
{
var entry = reader.Entry;
if (entry.IsDirectory)
{
var directoryName = Path.Combine(Path.GetFullPath(destinationDirectory), entry.Key);
Directory.CreateDirectory(directoryName);
continue;
}
var fileName = Path.Combine(Path.GetFullPath(destinationDirectory), entry.Key);
using var entryStream = new FileStream(fileName, FileMode.Create);
using (var stream = reader.OpenEntryStream())
{
stream.CopyTo(entryStream);
}
progress += 1d / count;
Console.WriteLine($"{progress} {fileName}");
}
return 0;
@@ -0,0 +1,13 @@
using Net.Sdk.Web;
namespace Daybreak.API.Controllers;
[GenerateController("api/test")]
public sealed class TestController
{
[GenerateGet("testing")]
public IResult GetTest(CancellationToken token)
{
return Results.Text("Hello from injected ASP-NET Core!", "text/plain");
}
}
+41
View File
@@ -0,0 +1,41 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net9.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<OutputType>Library</OutputType>
<RuntimeIdentifier>win-x86</RuntimeIdentifier>
<StripSymbols>true</StripSymbols>
<InteropExports>true</InteropExports>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<PublishAot>true</PublishAot>
<SelfContained>true</SelfContained>
<AspNetCoreHostingModel>OutOfProcess</AspNetCoreHostingModel>
<UseAppHost>false</UseAppHost>
<EnableIISSupport>false</EnableIISSupport>
<InvariantGlobalization>true</InvariantGlobalization>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Net.Sdk.Web.Extensions.SourceGenerators" Version="0.9.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Daybreak.Shared\Daybreak.Shared.csproj" />
</ItemGroup>
<PropertyGroup>
<DaybreakHostOutputDir>$(MSBuildProjectDirectory)\..\Daybreak\bin\x86\$(Configuration)\$(TargetFramework)\</DaybreakHostOutputDir>
<ShouldPublishAot>true</ShouldPublishAot>
</PropertyGroup>
<Target Name="PublishIntoDaybreak" AfterTargets="PostBuild" Condition="'$(ShouldPublishAot)'=='true'">
<Message Text="📦 dotnet-publish Daybreak.API → $(DaybreakHostOutputDir)" Importance="High" />
<Exec Command="dotnet publish &quot;$(MSBuildProjectFullPath)&quot; -c $(Configuration) -r win-x86 --self-contained true -o &quot;$(DaybreakHostOutputDir)&quot;" WorkingDirectory="$(ProjectDir)" />
</Target>
</Project>
+85
View File
@@ -0,0 +1,85 @@
using System.Net.NetworkInformation;
using System.Runtime.InteropServices;
using Daybreak.API.Extensions;
using Daybreak.API.Serialization;
using Net.Sdk.Web;
namespace Daybreak.API;
public static class EntryPoint
{
private const int StartPort = 5080;
[UnmanagedCallersOnly(EntryPoint = "ThreadInit"), STAThread]
public static int ThreadInit(IntPtr _, int __)
{
ConsoleExtensions.AllocateAnsiConsole();
var port = FindAvailablePort(StartPort);
if (port <= 0)
{
Console.WriteLine($"No available port found starting from {StartPort}");
return -1;
}
Console.WriteLine($"Starting Daybreak API on port {port}");
Task.Run(() => StartServer(port));
return port;
}
private static async Task StartServer(int port)
{
try
{
var builder = WebApplication.CreateBuilder();
builder.WebHost.UseUrls($"http://127.0.0.1:{port}");
builder.Services.ConfigureHttpJsonOptions(options =>
{
options.SerializerOptions.TypeInfoResolverChain.Insert(0, new ApiJsonSerializerContext());
});
builder.Logging.AddConsole();
builder.WithRoutes();
var app = builder.Build();
app.UseRoutes();
await app.RunAsync();
}
catch (Exception ex)
{
Console.Error.WriteLine(ex);
}
}
private static int FindAvailablePort(int startPort)
{
var port = startPort;
while (!IsPortAvailable(port))
{
port++;
if (port > 65535 || port < 0)
{
return -1;
}
}
return port;
}
private static bool IsPortAvailable(int port)
{
var ipProperties = IPGlobalProperties.GetIPGlobalProperties();
var tcpListeners = ipProperties.GetActiveTcpListeners();
if (tcpListeners.Any(endpoint => endpoint.Port == port))
{
return false;
}
var tcpConnections = ipProperties.GetActiveTcpConnections();
if (tcpConnections.Any(conn => conn.LocalEndPoint.Port == port))
{
return false;
}
return true;
}
}
@@ -0,0 +1,19 @@
namespace Daybreak.API.Extensions;
public static class ConsoleExtensions
{
public static void AllocateAnsiConsole()
{
NativeMethods.AllocConsole();
var handle = NativeMethods.GetStdHandle(NativeMethods.STD_OUTPUT_HANDLE);
if (!NativeMethods.GetConsoleMode(handle, out var mode))
{
Console.WriteLine("Failed to get console mode");
}
if (!NativeMethods.SetConsoleMode(handle, mode | NativeMethods.ENABLE_VIRTUAL_TERMINAL_PROCESSING | NativeMethods.ENABLE_PROCESSED_OUTPUT))
{
Console.WriteLine("Failed to enable virtual terminal processing");
}
}
}
+28
View File
@@ -0,0 +1,28 @@
using System.Runtime.InteropServices;
namespace Daybreak.API;
internal static partial class NativeMethods
{
public const int STD_OUTPUT_HANDLE = -11;
public const uint ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004;
public const uint ENABLE_PROCESSED_OUTPUT = 0x0001;
[LibraryImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static partial bool AllocConsole();
[LibraryImport("kernel32.dll", SetLastError = true)]
public static partial nint GetConsoleWindow();
[LibraryImport("kernel32.dll", SetLastError = true)]
public static partial nint GetStdHandle(int nStdHandle);
[LibraryImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static partial bool GetConsoleMode(nint hConsoleHandle, out uint lpMode);
[LibraryImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static partial bool SetConsoleMode(nint hConsoleHandle, uint dwMode);
}
@@ -0,0 +1,12 @@
{
"profiles": {
"Daybreak.API": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:51249;http://localhost:51250"
}
}
}
@@ -0,0 +1,8 @@
using System.Text.Json.Serialization;
namespace Daybreak.API.Serialization;
[JsonSerializable(typeof(string))]
public partial class ApiJsonSerializerContext : JsonSerializerContext
{
}
+6 -2
View File
@@ -2,10 +2,14 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Platforms>AnyCPU;x86;x64</Platforms>
<Platforms>AnyCPU;x86</Platforms>
<PublishSingleFile>True</PublishSingleFile>
<Self-Contained>True</Self-Contained>
<PublishReadyToRun>True</PublishReadyToRun>
<RuntimeIdentifier>win-x86</RuntimeIdentifier>
</PropertyGroup>
</Project>
+93 -36
View File
@@ -1,59 +1,116 @@
// See https://aka.ms/new-console-template for more information
using System.Diagnostics;
using System.IO.Compression;
using System.Text;
static void RenderProgressBar(int currentStep, int totalSteps, int barSize)
{
Console.CursorLeft = 0; // Reset cursor position to the start of the line
Console.Write("["); // Start of the progress bar
double pctComplete = (double)currentStep / totalSteps;
int chars = (int)Math.Round(pctComplete * barSize);
Console.Write(new string('=', chars)); // The 'completed' part of the bar
Console.Write(new string(' ', barSize - chars)); // The 'remaining' part of the bar
Console.Write("] ");
Console.Write($"{pctComplete:P0}"); // Display the percentage completed
}
const string tempFile = "tempfile.zip";
const string updatePkg = "update.pkg";
const string executableName = "Daybreak.exe";
Console.Title = "Daybreak Installer";
Console.WriteLine("Starting installation...");
if (File.Exists(tempFile) is false)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Unable to find launcher package. Aborting installation");
Console.ReadKey();
return;
}
while (Process.GetProcesses().Where(p => p.ProcessName == "Daybreak").FirstOrDefault()?.HasExited is false)
{
Console.WriteLine($"Detected Daybreak process is still running. Waiting 5s and retrying");
await Task.Delay(5000);
}
Console.WriteLine("Unpacking files...");
try
{
ZipFile.ExtractToDirectory(tempFile, AppContext.BaseDirectory, true);
}
catch
if (File.Exists(updatePkg))
{
Console.WriteLine("Unpacking files...");
}
using var fileStream = new FileStream(updatePkg, FileMode.Open);
var sizeBuffer = new byte[4];
var copyBuffer = new byte[1024];
while (fileStream.Position < fileStream.Length - 1)
{
/*
* For each file downloaded, we write to the package the following:
* Size of the name string
* UTF-8 encoded name string
* Size of the relative path string
* UTF-8 encoded relative path string
* Size of the binary
* Binary data
*/
Console.WriteLine("Deleting browser caches");
try
{
Directory.Delete("BrowserData", true);
}
catch(Exception)
{
}
try
{
Directory.Delete("Daybreak.exe.WebView2", true);
}
catch(Exception)
{
}
await fileStream.ReadAsync(sizeBuffer, 0, 4);
var fileNameSize = BitConverter.ToInt32(sizeBuffer, 0);
var fileNameBuffer = new byte[fileNameSize];
await fileStream.ReadAsync(fileNameBuffer, 0, fileNameSize);
var fileName = Encoding.UTF8.GetString(fileNameBuffer);
Console.WriteLine("Deleting package");
try
{
File.Delete(tempFile);
RenderProgressBar((int)fileStream.Position, (int)fileStream.Length, 40);
await fileStream.ReadAsync(sizeBuffer, 0, 4);
var relativePathSize = BitConverter.ToInt32(sizeBuffer, 0);
var relativePathBuffer = new byte[relativePathSize];
await fileStream.ReadAsync(relativePathBuffer, 0, relativePathSize);
var relativePath = Encoding.UTF8.GetString(relativePathBuffer);
RenderProgressBar((int)fileStream.Position, (int)fileStream.Length, 40);
await fileStream.ReadAsync(sizeBuffer, 0, 4);
var binarySize = BitConverter.ToInt32(sizeBuffer, 0);
var fileInfo = new FileInfo(relativePath);
fileInfo.Directory!.Create();
using var destinationStream = new FileStream(relativePath, FileMode.Create);
while(binarySize > 0)
{
var toRead = Math.Min(binarySize, copyBuffer.Length);
await fileStream.ReadAsync(copyBuffer, 0, toRead);
await destinationStream.WriteAsync(copyBuffer, 0, toRead);
binarySize -= toRead;
RenderProgressBar((int)fileStream.Position, (int)fileStream.Length, 40);
}
}
fileStream.Close();
fileStream.Dispose();
File.Delete(updatePkg);
}
catch (Exception e)
else if (File.Exists(tempFile))
{
Console.WriteLine($"Failed to delete {tempFile}.\n{e}");
Console.WriteLine("Unpacking files...");
try
{
ZipFile.ExtractToDirectory(tempFile, AppContext.BaseDirectory, true);
}
catch
{
}
Console.WriteLine("Deleting package");
try
{
File.Delete(tempFile);
}
catch (Exception e)
{
Console.WriteLine($"Failed to delete {tempFile}.\n{e}");
}
}
else
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Unable to find launcher package. Aborting installation");
Console.ReadKey();
return;
}
Console.WriteLine("Launching application");
@@ -1,4 +1,4 @@
namespace Daybreak.Configuration.Options;
namespace Daybreak.Shared.Configuration.Options;
public interface ITradeChatOptions
{
@@ -0,0 +1,51 @@
using Newtonsoft.Json;
using System;
namespace Daybreak.Shared.Converters;
public sealed class AttributeJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType) => true;
public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
{
if (!objectType.IsAssignableTo(typeof(Models.Guildwars.Attribute)))
{
return default;
}
switch (reader.TokenType)
{
case JsonToken.String:
var name = reader.ReadAsString();
if (name is null ||
!Models.Guildwars.Attribute.TryParse(name, out var namedAttribute))
{
return default;
}
return namedAttribute;
case JsonToken.Integer:
var id = reader.Value as long?;
if (id is not long ||
!Models.Guildwars.Attribute.TryParse((int)id.Value, out var parsedAttribute))
{
return default;
}
return parsedAttribute;
default:
return default;
}
}
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
if (value is not Models.Guildwars.Attribute attribute)
{
return;
}
writer.WriteValue(attribute.Id);
}
}
@@ -0,0 +1,33 @@
using System;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Media.Effects;
namespace Daybreak.Shared.Converters;
public sealed class BooleanToEffectConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is not bool boolean)
{
return default!;
}
if (parameter is not Effect effect)
{
return default!;
}
if (!boolean)
{
return default!;
}
return effect;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
@@ -4,7 +4,7 @@ using System.Globalization;
using System.Windows;
using System.Windows.Data;
namespace Daybreak.Converters;
namespace Daybreak.Shared.Converters;
public sealed class BooleanToGridLengthConverter : IValueConverter
{
@@ -4,7 +4,7 @@ using System.Globalization;
using System.Windows;
using System.Windows.Data;
namespace Daybreak.Converters;
namespace Daybreak.Shared.Converters;
public class BooleanToVisibilityConverter : IValueConverter
{
@@ -38,12 +38,12 @@ public class BooleanToVisibilityConverter : IValueConverter
}
var objValue = value.Cast<bool>();
if ((objValue && this.TriggerValue && this.IsHidden) || (!objValue && !this.TriggerValue && this.IsHidden))
if (objValue && this.TriggerValue && this.IsHidden || !objValue && !this.TriggerValue && this.IsHidden)
{
return Visibility.Hidden;
}
if ((objValue && this.TriggerValue && !this.IsHidden) || (!objValue && !this.TriggerValue && !this.IsHidden))
if (objValue && this.TriggerValue && !this.IsHidden || !objValue && !this.TriggerValue && !this.IsHidden)
{
return Visibility.Collapsed;
}
@@ -0,0 +1,52 @@
using Daybreak.Shared.Models.Guildwars;
using Newtonsoft.Json;
using System;
namespace Daybreak.Shared.Converters;
public sealed class CampaignJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType) => true;
public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
{
if (!objectType.IsAssignableTo(typeof(Campaign)))
{
return default;
}
switch (reader.TokenType)
{
case JsonToken.String:
var name = reader.ReadAsString();
if (name is null ||
!Campaign.TryParse(name, out var namedCampaign))
{
return default;
}
return namedCampaign;
case JsonToken.Integer:
var id = reader.Value as long?;
if (id is not long ||
!Campaign.TryParse((int)id.Value, out var parsedCampaign))
{
return default;
}
return parsedCampaign;
default:
return default;
}
}
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
if (value is not Campaign campaign)
{
return;
}
writer.WriteValue(campaign.Id);
}
}
@@ -0,0 +1,52 @@
using Daybreak.Shared.Models.Guildwars;
using Newtonsoft.Json;
using System;
namespace Daybreak.Shared.Converters;
public sealed class ContinentJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType) => true;
public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
{
if (!objectType.IsAssignableTo(typeof(Continent)))
{
return default;
}
switch (reader.TokenType)
{
case JsonToken.String:
var name = reader.ReadAsString();
if (name is null ||
!Continent.TryParse(name, out var namedContinent))
{
return default;
}
return namedContinent;
case JsonToken.Integer:
var id = reader.Value as long?;
if (id is not long ||
!Continent.TryParse((int)id.Value, out var parsedContinent))
{
return default;
}
return parsedContinent;
default:
return default;
}
}
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
if (value is not Continent continent)
{
return;
}
writer.WriteValue(continent.Id);
}
}
@@ -2,9 +2,10 @@
using System.Globalization;
using System.Windows.Data;
namespace Daybreak.Converters;
namespace Daybreak.Shared.Converters;
public sealed class DateTimeConverter : IValueConverter
{
public string? Format { get; set; }
public bool LongTime { get; set; }
public bool LongDate { get; set; }
@@ -15,6 +16,11 @@ public sealed class DateTimeConverter : IValueConverter
return string.Empty;
}
if (this.Format is not null)
{
return dateTime.ToString(this.Format);
}
if (this.LongTime)
{
return dateTime.ToLongTimeString();
@@ -0,0 +1,24 @@
using System;
using System.Globalization;
using System.Windows.Data;
namespace Daybreak.Shared.Converters;
public sealed class DoubleMultiplierConverter : IValueConverter
{
public double Multiplier { get; set; }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is not double d)
{
return value;
}
return d * this.Multiplier;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
@@ -0,0 +1,25 @@
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
namespace Daybreak.Shared.Converters;
public sealed class EqualityToVisibilityConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values.Length != 2)
{
return Visibility.Collapsed;
}
return values[0] == values[1] ? Visibility.Visible : Visibility.Collapsed;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
@@ -0,0 +1,72 @@
using Daybreak.Shared;
using Daybreak.Shared.Models.Guildwars;
using Daybreak.Shared.Services.Events;
using ExCSS;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Globalization;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Shapes;
namespace Daybreak.Shared.Converters;
public sealed class EventCalendarDayToBrushConverter : IValueConverter
{
private readonly EventToBrushConverter eventToBrushConverter = new();
private readonly IEventService eventService = Global.GlobalServiceProvider.GetRequiredService<IEventService>();
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is not DateTime dayDate)
{
throw new InvalidOperationException($"Unable to convert from {value.GetType().Name}");
}
dayDate = new DateTime(dayDate.Year, dayDate.Month, dayDate.Day, 19, 0, 0);
var activeEvents = this.eventService.GetActiveEvents(dayDate).ToList();
if (activeEvents.Count == 0)
{
return Brushes.Transparent;
}
if (activeEvents.Count == 1 &&
activeEvents.FirstOrDefault() is Event ev)
{
return this.eventToBrushConverter.Convert(ev, typeof(Brush), parameter, culture);
}
var brushes = this.eventService.GetActiveEvents(dayDate).Select(e => this.eventToBrushConverter.Convert(e, typeof(Brush), parameter, culture)).OfType<SolidColorBrush>().ToList();
var canvas = new Canvas();
double width = 1.0 / brushes.Count; // Assuming a normalized width for each color segment
for (int i = 0; i < brushes.Count; i++)
{
var rect = new Rectangle
{
Width = width,
Height = 1,
Fill = brushes[i],
RenderTransform = new TranslateTransform(i * width, 0)
};
canvas.Children.Add(rect);
}
return new VisualBrush
{
Visual = canvas,
Stretch = Stretch.None,
TileMode = TileMode.None,
Viewbox = new Rect(0, 0, 1, 1),
ViewboxUnits = BrushMappingMode.RelativeToBoundingBox,
Transform = new RotateTransform(45, 0.5, 0.5)
};
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
@@ -0,0 +1,46 @@
using Daybreak.Shared.Models;
using Daybreak.Shared.Models.Guildwars;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Media;
using Brush = System.Windows.Media.Brush;
namespace Daybreak.Shared.Converters;
public sealed class EventToBrushConverter : IValueConverter
{
private static readonly Dictionary<Event, Brush> EventMapping = new()
{
{ Event.CanthanNewYear, new SolidColorBrush(ColorPalette.Amber) },
{ Event.LuckyTreatsWeek, new SolidColorBrush(ColorPalette.Green) },
{ Event.AprilFoolsDay, new SolidColorBrush(ColorPalette.DeepPurple) },
{ Event.SweetTreatsWeek, new SolidColorBrush(ColorPalette.Indigo) },
{ Event.AnniversaryCelebration, new SolidColorBrush(ColorPalette.Yellow) },
{ Event.DragonFestival, new SolidColorBrush(ColorPalette.DeepOrange) },
{ Event.WintersdayInJuly, new SolidColorBrush(ColorPalette.LightBlue) },
{ Event.WayfarersReverie, new SolidColorBrush(ColorPalette.Magenta) },
{ Event.PirateWeek, new SolidColorBrush(ColorPalette.Gold) },
{ Event.BreastCancerAwarenessMonth, new SolidColorBrush(ColorPalette.Pink) },
{ Event.Halloween, new SolidColorBrush(ColorPalette.Orange) },
{ Event.SpecialTreatsWeek, new SolidColorBrush(ColorPalette.Lime) },
{ Event.WintersdayJanuary, new SolidColorBrush(ColorPalette.BlueGrey) },
{ Event.WintersdayDecember, new SolidColorBrush(ColorPalette.BlueGrey) }
};
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is not Event e ||
targetType != typeof(Brush))
{
throw new InvalidOperationException($"Unable to convert from {value.GetType().Name} to {targetType.Name}");
}
return EventMapping[e];
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
@@ -3,7 +3,7 @@ using System.Globalization;
using System.Windows;
using System.Windows.Data;
namespace Daybreak.Converters;
namespace Daybreak.Shared.Converters;
public class HiddenWhenNull : IValueConverter
{
@@ -0,0 +1,44 @@
using System;
using System.Globalization;
using System.Windows.Data;
namespace Daybreak.Shared.Converters;
public sealed class IntToStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (targetType == typeof(string) &&
value is int i)
{
return i.ToString();
}
else if(targetType == typeof(int) &&
value is string s)
{
return int.Parse(s);
}
else
{
throw new InvalidOperationException($"Unable to convert from {value.GetType().Name} to {targetType.Name}");
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (targetType == typeof(string) &&
value is int i)
{
return i.ToString();
}
else if (targetType == typeof(int) &&
value is string s)
{
return int.Parse(s);
}
else
{
throw new InvalidOperationException($"Unable to convert from {value.GetType().Name} to {targetType.Name}");
}
}
}
@@ -1,7 +1,7 @@
using System;
using System.Windows.Data;
namespace Daybreak.Converters;
namespace Daybreak.Shared.Converters;
public class InverseBooleanConverter : IValueConverter
{
@@ -0,0 +1,52 @@
using Daybreak.Shared.Models.Guildwars;
using Newtonsoft.Json;
using System;
namespace Daybreak.Shared.Converters;
public sealed class ItemBaseJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType) => true;
public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
{
if (!objectType.IsAssignableTo(typeof(ItemBase)))
{
return default;
}
switch (reader.TokenType)
{
case JsonToken.String:
var name = reader.ReadAsString();
if (name is not string ||
!ItemBase.TryParse(name, out var namedItem))
{
return default;
}
return namedItem;
case JsonToken.Integer:
var id = reader.Value as long?;
if (id is not long ||
!ItemBase.TryParse((int)id.Value, null, out var parsedItem))
{
return default;
}
return parsedItem;
default:
return default;
}
}
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
if (value is not ItemBase itemBase)
{
return;
}
writer.WriteValue(itemBase.Id);
}
}
@@ -0,0 +1,36 @@
using Daybreak.Shared.Models.Guildwars;
using System;
using System.Globalization;
using System.Windows.Data;
namespace Daybreak.Shared.Converters;
public sealed class ItemBaseToIntConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is int i)
{
return ItemBase.Parse(i, modifiers: null);
}
else if(value is ItemBase itemBase)
{
return itemBase.Id;
}
throw new InvalidOperationException($"Unable to convert value of type {value.GetType().Name}");
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is int i)
{
return ItemBase.Parse(i, modifiers: null);
}
else if (value is ItemBase itemBase)
{
return itemBase.Id;
}
throw new InvalidOperationException($"Unable to convert value of type {value.GetType().Name}");
}
}
@@ -0,0 +1,36 @@
using Daybreak.Shared.Models.Guildwars;
using System;
using System.Globalization;
using System.Windows.Data;
namespace Daybreak.Shared.Converters;
public sealed class ItemBaseToStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is string s)
{
return ItemBase.Parse(s);
}
else if(value is ItemBase itemBase)
{
return itemBase.Name ?? string.Empty;
}
throw new InvalidOperationException($"Unable to convert value of type {value.GetType().Name}");
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is string s)
{
return ItemBase.Parse(s);
}
else if (value is ItemBase itemBase)
{
return itemBase.Name ?? string.Empty;
}
throw new InvalidOperationException($"Unable to convert value of type {value.GetType().Name}");
}
}
@@ -0,0 +1,52 @@
using Daybreak.Shared.Models.Guildwars;
using Newtonsoft.Json;
using System;
namespace Daybreak.Shared.Converters;
public sealed class MapJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType) => true;
public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
{
if (!objectType.IsAssignableTo(typeof(Map)))
{
return default;
}
switch (reader.TokenType)
{
case JsonToken.String:
var name = reader.ReadAsString();
if (name is null ||
!Map.TryParse(name, out var namedMap))
{
return default;
}
return namedMap;
case JsonToken.Integer:
var id = reader.Value as long?;
if (id is not long ||
!Map.TryParse((int)id.Value, out var parsedMap))
{
return default;
}
return parsedMap;
default:
return default;
}
}
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
if (value is not Map map)
{
return;
}
writer.WriteValue(map.Id);
}
}
@@ -2,7 +2,7 @@
using System.Globalization;
using System.Windows.Data;
namespace Daybreak.Converters;
namespace Daybreak.Shared.Converters;
public class MenuButtonHighlightConverter : IValueConverter
{
@@ -0,0 +1,53 @@
using Daybreak.Shared.Models.Guildwars;
using Newtonsoft.Json;
using System;
using System.Linq;
namespace Daybreak.Shared.Converters;
public sealed class NpcJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType) => true;
public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
{
if (!objectType.IsAssignableTo(typeof(Npc)))
{
return default;
}
switch (reader.TokenType)
{
case JsonToken.String:
var name = reader.ReadAsString();
if (name is null ||
!Npc.TryParse(name, out var namedNpc))
{
return default;
}
return namedNpc;
case JsonToken.Integer:
var id = reader.Value as long?;
if (id is not long ||
!Npc.TryParse((int)id.Value, out var parsedNpc))
{
return default;
}
return parsedNpc;
default:
return default;
}
}
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
if (value is not Npc npc)
{
return;
}
writer.WriteValue(npc.Ids.FirstOrDefault());
}
}
@@ -0,0 +1,44 @@
using System;
using System.Globalization;
using System.Windows.Data;
namespace Daybreak.Shared.Converters;
public sealed class PriceToStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (targetType != typeof(string))
{
throw new InvalidOperationException($"Unable to convert to {targetType.Name}");
}
var price = value switch
{
byte byteVal => byteVal,
short shortVal => shortVal,
ushort ushortVal => ushortVal,
int intVal => intVal,
uint uintVal => uintVal,
long longVal => longVal,
ulong ulongVal => ulongVal,
decimal decimalVal => (double)decimalVal,
float floatVal => (double)floatVal,
double doubleVal => (double)doubleVal,
_ => throw new InvalidOperationException($"Unable to convert from {value.GetType().Name}")
};
var suffix = 'g';
if (price > 1000)
{
price /= 1000;
suffix = 'k';
}
return $"{price}{suffix}";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
@@ -0,0 +1,52 @@
using Daybreak.Shared.Models.Guildwars;
using Newtonsoft.Json;
using System;
namespace Daybreak.Shared.Converters;
public sealed class ProfessionJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType) => true;
public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
{
if (!objectType.IsAssignableTo(typeof(Profession)))
{
return default;
}
switch (reader.TokenType)
{
case JsonToken.String:
var name = reader.ReadAsString();
if (name is null ||
!Profession.TryParse(name, out var namedProfession))
{
return default;
}
return namedProfession;
case JsonToken.Integer:
var id = reader.Value as long?;
if (id is not long ||
!Profession.TryParse((int)id.Value, out var parsedProfession))
{
return default;
}
return parsedProfession;
default:
return default;
}
}
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
if (value is not Profession profession)
{
return;
}
writer.WriteValue(profession.Id);
}
}
@@ -0,0 +1,52 @@
using Daybreak.Shared.Models.Guildwars;
using Newtonsoft.Json;
using System;
namespace Daybreak.Shared.Converters;
public sealed class QuestJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType) => true;
public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
{
if (!objectType.IsAssignableTo(typeof(Quest)))
{
return default;
}
switch (reader.TokenType)
{
case JsonToken.String:
var name = reader.ReadAsString();
if (name is null ||
!Quest.TryParse(name, out var namedQuest))
{
return default;
}
return namedQuest;
case JsonToken.Integer:
var id = reader.Value as long?;
if (id is not long ||
!Quest.TryParse((int)id.Value, out var parsedQuest))
{
return default;
}
return parsedQuest;
default:
return default;
}
}
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
if (value is not Quest quest)
{
return;
}
writer.WriteValue(quest.Id);
}
}
@@ -0,0 +1,52 @@
using Daybreak.Shared.Models.Guildwars;
using Newtonsoft.Json;
using System;
namespace Daybreak.Shared.Converters;
public sealed class RegionJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType) => true;
public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
{
if (!objectType.IsAssignableTo(typeof(Region)))
{
return default;
}
switch (reader.TokenType)
{
case JsonToken.String:
var name = reader.ReadAsString();
if (name is null ||
!Region.TryParse(name, out var namedRegion))
{
return default;
}
return namedRegion;
case JsonToken.Integer:
var id = reader.Value as long?;
if (id is not long ||
!Region.TryParse((int)id.Value, out var parsedRegion))
{
return default;
}
return parsedRegion;
default:
return default;
}
}
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
if (value is not Region region)
{
return;
}
writer.WriteValue(region.Id);
}
}
@@ -0,0 +1,52 @@
using Daybreak.Shared.Models.Guildwars;
using Newtonsoft.Json;
using System;
namespace Daybreak.Shared.Converters;
public sealed class SkillJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType) => true;
public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
{
if (!objectType.IsAssignableTo(typeof(Skill)))
{
return default;
}
switch (reader.TokenType)
{
case JsonToken.String:
var name = reader.ReadAsString();
if (name is null ||
!Skill.TryParse(name, out var namedSkill))
{
return default;
}
return namedSkill;
case JsonToken.Integer:
var id = reader.Value as long?;
if (id is not long ||
!Skill.TryParse((int)id.Value, out var parsedSkill))
{
return default;
}
return parsedSkill;
default:
return default;
}
}
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
if (value is not Skill skill)
{
return;
}
writer.WriteValue(skill.Id);
}
}
@@ -2,7 +2,7 @@
using System.Globalization;
using System.Windows.Data;
namespace Daybreak.Converters;
namespace Daybreak.Shared.Converters;
public class TileButtonHighlightConverter : IValueConverter
{
@@ -2,7 +2,7 @@
using System.Globalization;
using System.Windows.Data;
namespace Daybreak.Converters;
namespace Daybreak.Shared.Converters;
public sealed class TimeSinceDateTimeConverter : IValueConverter
{
@@ -101,6 +101,6 @@ public sealed class TimeSinceDateTimeConverter : IValueConverter
currentYear--;
}
return $"{yearCount} years{(yearCount > 1 ? PluralAppend : string.Empty)} ago";
return $"{yearCount} year{(yearCount > 1 ? PluralAppend : string.Empty)} ago";
}
}
@@ -0,0 +1,35 @@
using System;
using System.Globalization;
using System.Windows.Data;
namespace Daybreak.Shared.Converters;
public sealed class TimespanToETAConverter : IValueConverter
{
private const char PluralAppend = 's';
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return GetETAString(value);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
private static string GetETAString(object obj)
{
if (obj is not TimeSpan timeSpan)
{
return string.Empty;
}
if ((int)timeSpan.TotalDays > 0)
{
return $"{(int)timeSpan.TotalDays} day{((int)timeSpan.TotalDays > 1 ? PluralAppend : string.Empty)} remaining";
}
return $"{timeSpan.Hours:D2}:{timeSpan.Minutes:D2}:{timeSpan.Seconds:D2} remaining";
}
}
@@ -0,0 +1,52 @@
using Daybreak.Shared.Models.Guildwars;
using Newtonsoft.Json;
using System;
namespace Daybreak.Shared.Converters;
public sealed class TitleJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType) => true;
public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
{
if (!objectType.IsAssignableTo(typeof(Title)))
{
return default;
}
switch (reader.TokenType)
{
case JsonToken.String:
var name = reader.ReadAsString();
if (name is null ||
!Title.TryParse(name, out var namedTitle))
{
return default;
}
return namedTitle;
case JsonToken.Integer:
var id = reader.Value as long?;
if (id is not long ||
!Title.TryParse((int)id.Value, out var parsedTitle))
{
return default;
}
return parsedTitle;
default:
return default;
}
}
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
if (value is not Title title)
{
return;
}
writer.WriteValue(title.Id);
}
}
@@ -0,0 +1,77 @@
using Daybreak.Shared.Models.Trade;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
namespace Daybreak.Shared.Converters;
public sealed class TradeAlertConverter : JsonConverter<ITradeAlert>
{
public override ITradeAlert? ReadJson(JsonReader reader, Type objectType, ITradeAlert? existingValue, bool hasExistingValue, JsonSerializer serializer)
{
var jObject = JObject.Load(reader).ToObject<dynamic>();
if (jObject is null)
{
throw new InvalidOperationException($"Unable to deserialize {nameof(ITradeAlert)}");
}
if (jObject[nameof(TradeAlert.MessageCheck)] is null)
{
return new QuoteAlert
{
Name = jObject[nameof(QuoteAlert.Name)],
Id = jObject[nameof(QuoteAlert.Id)],
Enabled = jObject[nameof(QuoteAlert.Enabled)],
UpperPriceTarget = jObject[nameof(QuoteAlert.UpperPriceTarget)],
LowerPriceTarget = jObject[nameof(QuoteAlert.LowerPriceTarget)],
UpperPriceTargetEnabled = jObject[nameof(QuoteAlert.UpperPriceTargetEnabled)],
LowerPriceTargetEnabled = jObject[nameof(QuoteAlert.LowerPriceTargetEnabled)],
ItemId = jObject[nameof(QuoteAlert.ItemId)]
};
}
else
{
return new TradeAlert
{
Name = jObject[nameof(TradeAlert.Name)],
Id = jObject[nameof(TradeAlert.Id)],
Enabled = jObject[nameof(TradeAlert.Enabled)],
MessageCheck = jObject[nameof(TradeAlert.MessageCheck)],
MessageRegexCheck = jObject[nameof(TradeAlert.MessageRegexCheck)],
SenderCheck = jObject[nameof(TradeAlert.SenderCheck)],
SenderRegexCheck = jObject[nameof(TradeAlert.SenderRegexCheck)]
};
}
}
public override void WriteJson(JsonWriter writer, ITradeAlert? value, JsonSerializer serializer)
{
if (value is null)
{
serializer.Serialize(writer, null);
return;
}
var jObject = new JObject();
jObject[nameof(ITradeAlert.Name)] = value.Name;
jObject[nameof(ITradeAlert.Enabled)] = value.Enabled;
jObject[nameof(ITradeAlert.Id)] = value.Id;
if (value is TradeAlert tradeAlert)
{
jObject[nameof(TradeAlert.MessageCheck)] = tradeAlert.MessageCheck;
jObject[nameof(TradeAlert.MessageRegexCheck)] = tradeAlert.MessageRegexCheck;
jObject[nameof(TradeAlert.SenderCheck)] = tradeAlert.SenderCheck;
jObject[nameof(TradeAlert.SenderRegexCheck)] = tradeAlert.SenderRegexCheck;
}
else if (value is QuoteAlert quoteAlert)
{
jObject[nameof(QuoteAlert.TraderQuoteType)] = quoteAlert.TraderQuoteType.ToString();
jObject[nameof(QuoteAlert.ItemId)] = quoteAlert.ItemId;
jObject[nameof(QuoteAlert.UpperPriceTarget)] = quoteAlert.UpperPriceTarget;
jObject[nameof(QuoteAlert.UpperPriceTargetEnabled)] = quoteAlert.UpperPriceTargetEnabled;
jObject[nameof(QuoteAlert.LowerPriceTarget)] = quoteAlert.LowerPriceTarget;
jObject[nameof(QuoteAlert.LowerPriceTargetEnabled)] = quoteAlert.LowerPriceTargetEnabled;
}
serializer.Serialize(writer, jObject);
}
}
@@ -0,0 +1,33 @@
using Daybreak.Shared.Models.Trade;
using System;
using System.Globalization;
using System.Windows.Data;
namespace Daybreak.Shared.Converters;
public sealed class TraderQuoteTypeToStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (targetType != typeof(string))
{
throw new InvalidOperationException($"Unable to convert from {nameof(TraderQuoteType)} to {targetType.Name}");
}
return value?.ToString() ?? string.Empty;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is not string s)
{
throw new InvalidOperationException($"Unable to convert to {targetType.Name}");
}
if (!Enum.TryParse<TraderQuoteType>(s, out var enumValue))
{
throw new InvalidOperationException($"Invalid string value provided {s}");
}
return enumValue;
}
}
+60
View File
@@ -0,0 +1,60 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<UseWPF>true</UseWPF>
<LangVersion>preview</LangVersion>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AvalonEdit" Version="6.3.1.120" />
<PackageReference Include="DiffPlex" Version="1.7.2" />
<PackageReference Include="HtmlAgilityPack" Version="1.12.1" />
<PackageReference Include="ini-parser-netstandard" Version="2.5.3" />
<PackageReference Include="LiveChartsCore.SkiaSharpView.WPF" Version="2.0.0-rc2" />
<PackageReference Include="MahApps.Metro" Version="2.4.10" />
<PackageReference Include="Microsoft.CorrelationVector" Version="1.0.42" />
<PackageReference Include="Microsoft.Data.Sqlite" Version="9.0.5" />
<PackageReference Include="Microsoft.Data.Sqlite.Core" Version="9.0.5" />
<PackageReference Include="Microsoft.Extensions.Configuration.UserSecrets" Version="9.0.5" />
<PackageReference Include="Microsoft.Extensions.Http" Version="9.0.5" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.5" />
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.3240.44" />
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.135" />
<PackageReference Include="NAudio" Version="2.2.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="PeNet" Version="5.1.0" />
<PackageReference Include="Plumsy" Version="1.1.0" />
<PackageReference Include="securifybv.ShellLink" Version="0.1.0" />
<PackageReference Include="Slim" Version="1.9.2" />
<PackageReference Include="Squealify" Version="0.8.2.2" />
<PackageReference Include="Svg" Version="3.4.7" />
<PackageReference Include="System.Formats.Asn1" Version="9.0.5" />
<PackageReference Include="System.IO.Compression" Version="4.3.0" />
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
<PackageReference Include="System.Reflection.Metadata" Version="9.0.5" />
<PackageReference Include="System.Text.Encoding.CodePages" Version="9.0.5" />
<PackageReference Include="System.Text.Json" Version="9.0.5" />
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" />
<PackageReference Include="SystemExtensions.NetCore" Version="1.6.11" />
<PackageReference Include="SystemExtensions.NetStandard" Version="1.6.11" />
<PackageReference Include="SystemExtensions.NetStandard.DependencyInjection" Version="1.6.9" />
<PackageReference Include="WpfExtended" Version="0.7.9" />
<PackageReference Include="WpfExtended.SourceGeneration" Version="0.3.0" />
<PackageReference Include="WpfScreenHelper" Version="2.1.1" />
<PackageReference Include="WriteableBitmapEx" Version="1.6.8" />
</ItemGroup>
<Target Name="RemoveDuplicateAnalyzers" BeforeTargets="CoreCompile">
<!-- Work around https://github.com/dotnet/wpf/issues/6792 -->
<ItemGroup>
<FilteredAnalyzer Include="@(Analyzer-&gt;Distinct())" />
<Analyzer Remove="@(Analyzer)" />
<Analyzer Include="@(FilteredAnalyzer)" />
</ItemGroup>
</Target>
</Project>
@@ -1,7 +1,6 @@
using System;
using System.Runtime.Serialization;
namespace Daybreak.Exceptions;
namespace Daybreak.Shared.Exceptions;
public sealed class CredentialsNotFoundException : Exception
{
@@ -13,9 +12,6 @@ public sealed class CredentialsNotFoundException : Exception
{
}
public CredentialsNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
public CredentialsNotFoundException(string message, Exception innerException) : base(message, innerException)
{
@@ -1,7 +1,6 @@
using System;
using System.Runtime.Serialization;
namespace Daybreak.Exceptions;
namespace Daybreak.Shared.Exceptions;
public sealed class ExecutableNotFoundException : Exception
{
@@ -13,9 +12,6 @@ public sealed class ExecutableNotFoundException : Exception
{
}
public ExecutableNotFoundException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
public ExecutableNotFoundException(string message, Exception innerException) : base(message, innerException)
{
@@ -1,7 +1,6 @@
using System;
using System.Runtime.Serialization;
namespace Daybreak.Exceptions;
namespace Daybreak.Shared.Exceptions;
public sealed class FatalException : Exception
{
@@ -13,10 +12,6 @@ public sealed class FatalException : Exception
{
}
public FatalException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
public FatalException(string message, Exception innerException) : base(message, innerException)
{
}
+12
View File
@@ -0,0 +1,12 @@
using System;
using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("Daybreak")]
namespace Daybreak.Shared;
public static class Global
{
//Will get set by Daybreak on application startup
public static IServiceProvider GlobalServiceProvider { get; internal set; } = default!;
}
@@ -0,0 +1,9 @@
using System.Diagnostics;
namespace Daybreak.Shared.Models;
public readonly struct ApplicationLauncherContext
{
public string ExecutablePath { get; init; }
public Process Process { get; init; }
public uint ProcessId { get; init; }
}
@@ -0,0 +1,8 @@
using System.Windows.Media;
namespace Daybreak.Shared.Models;
public sealed class BackgroundResponse
{
public ImageSource? ImageSource { get; set; }
public string? CreditText { get; set; }
}
@@ -2,7 +2,7 @@
using System.Collections.ObjectModel;
using System.Collections.Specialized;
namespace Daybreak.Models;
namespace Daybreak.Shared.Models;
public class BatchedObservableCollection<T> : ObservableCollection<T>
{
@@ -0,0 +1,8 @@
using System.Collections.Generic;
namespace Daybreak.Shared.Models.Browser;
public sealed class BrowserHistory
{
public List<string> History { get; set; } = [];
public int CurrentPosition { get; set; } = -1;
}
@@ -1,7 +1,7 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace Daybreak.Models.Browser;
namespace Daybreak.Shared.Models.Browser;
public class BrowserPayload
{
@@ -9,7 +9,9 @@ public class BrowserPayload
public enum PayloadKeys
{
None,
ContextMenu
ContextMenu,
XButton1Pressed,
XButton2Pressed
}
[JsonProperty(nameof(Key))]
@@ -1,4 +1,4 @@
namespace Daybreak.Models.Browser;
namespace Daybreak.Shared.Models.Browser;
public sealed class DownloadPayload
{
@@ -1,6 +1,6 @@
using Newtonsoft.Json;
namespace Daybreak.Models.Browser;
namespace Daybreak.Shared.Models.Browser;
public sealed class OnContextMenuPayload
{
@@ -10,4 +10,6 @@ public sealed class OnContextMenuPayload
public double Y { get; set; }
[JsonProperty(nameof(Selection))]
public string? Selection { get; set; }
[JsonProperty(nameof(Url))]
public string? Url { get; set; }
}
@@ -0,0 +1,9 @@
using Daybreak.Shared.Models.Builds;
namespace Daybreak.Shared.Models;
public sealed class BuildWithTemplateCode
{
public IBuildEntry? Build { get; set; }
public string? TemplateCode { get; set; }
}
@@ -1,13 +1,15 @@
using System.ComponentModel;
using Daybreak.Models.Guildwars;
using Attribute = Daybreak.Shared.Models.Guildwars.Attribute;
namespace Daybreak.Models.Builds;
namespace Daybreak.Shared.Models.Builds;
public sealed class AttributeEntry : INotifyPropertyChanged
{
private Attribute? attribute;
private int points;
public event PropertyChangedEventHandler? PropertyChanged;
public Attribute? Attribute
{
get => this.attribute;
@@ -26,6 +28,5 @@ public sealed class AttributeEntry : INotifyPropertyChanged
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.Points)));
}
}
public event PropertyChangedEventHandler? PropertyChanged;
public override string ToString() => $"{this.Attribute?.Name} - {this.Points}";
}
@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
namespace Daybreak.Shared.Models.Builds;
public interface IBuildEntry
{
public DateTimeOffset CreationTime { get; set; }
public Dictionary<string, string>? Metadata { get; set; }
public string? SourceUrl { get; set; }
public string? PreviousName { get; set; }
public string? Name { get; set; }
}
@@ -1,135 +1,182 @@
using Daybreak.Models.Guildwars;
using Daybreak.Shared.Models.Guildwars;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using Attribute = Daybreak.Shared.Models.Guildwars.Attribute;
namespace Daybreak.Models.Builds;
public sealed class BuildEntry : INotifyPropertyChanged
namespace Daybreak.Shared.Models.Builds;
public sealed class SingleBuildEntry : BuildEntryBase, IBuildEntry, INotifyPropertyChanged, IEquatable<SingleBuildEntry>
{
public event PropertyChangedEventHandler? PropertyChanged;
private string? name;
private Build? build;
public string? PreviousName { get; set; }
public string? Name
{
get => this.name;
set
{
this.name = value;
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.Name)));
}
}
public Build? Build
{
get => this.build;
set
{
this.build = value;
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.Build)));
}
}
public Profession Primary
{
get => this.Build!.Primary;
get;
set
{
this.Build!.Primary = value;
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.Primary)));
if (value is null)
{
return;
}
field = value;
this.UpdateAttributes();
this.OnPropertyChanged(nameof(this.Primary));
}
}
} = Profession.None;
public Profession Secondary
{
get => this.Build!.Secondary;
get;
set
{
this.Build!.Secondary = value;
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.Secondary)));
if (value is null)
{
return;
}
field = value;
this.UpdateAttributes();
this.OnPropertyChanged(nameof(this.Secondary));
}
}
} = Profession.None;
public List<AttributeEntry> Attributes
{
get => this.Build!.Attributes;
get;
set
{
this.Build!.Attributes = value;
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.Attributes)));
if (value is null)
{
return;
}
field = value;
this.UpdateSkills();
this.OnPropertyChanged(nameof(this.Attributes));
}
}
} = [];
public List<Skill> Skills
{
get;
set
{
if (value is null)
{
return;
}
field = value;
this.OnPropertyChanged(nameof(this.Skills));
}
} = [Skill.NoSkill, Skill.NoSkill, Skill.NoSkill, Skill.NoSkill, Skill.NoSkill, Skill.NoSkill, Skill.NoSkill, Skill.NoSkill];
public Skill FirstSkill
{
get => this.Build!.Skills[0];
get => this.Skills[0];
set
{
this.Build!.Skills[0] = value;
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.FirstSkill)));
if (value is null)
{
return;
}
this.Skills[0] = value;
this.OnPropertyChanged(nameof(this.FirstSkill));
}
}
public Skill SecondSkill
{
get => this.Build!.Skills[1];
get => this.Skills[1];
set
{
this.Build!.Skills[1] = value;
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.SecondSkill)));
if (value is null)
{
return;
}
this.Skills[1] = value;
this.OnPropertyChanged(nameof(this.SecondSkill));
}
}
public Skill ThirdSkill
{
get => this.Build!.Skills[2];
get => this.Skills[2];
set
{
this.Build!.Skills[2] = value;
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.ThirdSkill)));
if (value is null)
{
return;
}
this.Skills[2] = value;
this.OnPropertyChanged(nameof(this.ThirdSkill));
}
}
public Skill FourthSkill
{
get => this.Build!.Skills[3];
get => this.Skills[3];
set
{
this.Build!.Skills[3] = value;
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.FourthSkill)));
if (value is null)
{
return;
}
this.Skills[3] = value;
this.OnPropertyChanged(nameof(this.FourthSkill));
}
}
public Skill FifthSkill
{
get => this.Build!.Skills[4];
get => this.Skills[4];
set
{
this.Build!.Skills[4] = value;
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.FifthSkill)));
if (value is null)
{
return;
}
this.Skills[4] = value;
this.OnPropertyChanged(nameof(this.FifthSkill));
}
}
public Skill SixthSkill
{
get => this.Build!.Skills[5];
get => this.Skills[5];
set
{
this.Build!.Skills[5] = value;
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.SixthSkill)));
if (value is null)
{
return;
}
this.Skills[5] = value;
this.OnPropertyChanged(nameof(this.SixthSkill));
}
}
public Skill SeventhSkill
{
get => this.Build!.Skills[6];
get => this.Skills[6];
set
{
this.Build!.Skills[6] = value;
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.SeventhSkill)));
if (value is null)
{
return;
}
this.Skills[6] = value;
this.OnPropertyChanged(nameof(this.SeventhSkill));
}
}
public Skill EigthSkill
{
get => this.Build!.Skills[7];
get => this.Skills[7];
set
{
this.Build!.Skills[7] = value;
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.EigthSkill)));
if (value is null)
{
return;
}
this.Skills[7] = value;
this.OnPropertyChanged(nameof(this.EigthSkill));
}
}
@@ -212,4 +259,24 @@ public sealed class BuildEntry : INotifyPropertyChanged
this.EigthSkill = Skill.NoSkill;
}
}
public bool Equals(SingleBuildEntry? other)
{
return this.Name == other?.Name &&
this.PreviousName == other?.PreviousName &&
this.SourceUrl == other?.SourceUrl &&
this.Primary == other?.Primary &&
this.Secondary == other?.Secondary &&
this.Skills.SequenceEqual(other.Skills);
}
public override bool Equals(object? obj)
{
return this.Equals(obj as SingleBuildEntry);
}
public override int GetHashCode()
{
return HashCode.Combine(this.Name, this.PreviousName, this.SourceUrl, this.Primary.Name, this.Secondary.Name, string.Join(';', this.Skills.Select(s => s.Id)));
}
}
@@ -0,0 +1,42 @@
using Daybreak.Shared.Models.Guildwars;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Daybreak.Shared.Models.Builds;
public sealed class TeamBuildEntry : BuildEntryBase, IEquatable<TeamBuildEntry>
{
public List<SingleBuildEntry> Builds
{
get;
set
{
field = value;
this.OnPropertyChanged(nameof(this.Builds));
}
} = [];
public bool Equals(TeamBuildEntry? other)
{
return this.Name == other?.Name &&
this.PreviousName == other?.PreviousName &&
this.SourceUrl == other?.SourceUrl &&
this.Builds.Select((thisBuild, index) =>
{
var otherBuild = other?.Builds.Skip(index).FirstOrDefault();
return thisBuild.Primary == otherBuild?.Primary &&
thisBuild.Secondary == otherBuild?.Secondary &&
thisBuild.Skills.SequenceEqual(otherBuild.Skills);
}).All(result => result);
}
public override bool Equals(object? obj)
{
return this.Equals(obj as TeamBuildEntry);
}
public override int GetHashCode()
{
return HashCode.Combine(this.Name, this.PreviousName, this.SourceUrl, this.Builds.Select(c => c.GetHashCode()));
}
}
@@ -1,7 +1,7 @@
using System.Collections.Generic;
using System.Windows.Media;
namespace Daybreak.Models;
namespace Daybreak.Shared.Models;
public static class ColorPalette
{
public readonly static Color Red = Color.FromArgb(255, 213, 0, 0);
@@ -24,8 +24,8 @@ public static class ColorPalette
public readonly static Color BlueGrey = Color.FromArgb(255, 96, 125, 139);
public readonly static Color Grey = Color.FromArgb(255, 158, 158, 158);
public readonly static List<Color> Colors = new()
{
public readonly static List<Color> Colors =
[
Pink,
Amber,
Purple,
@@ -45,5 +45,5 @@ public static class ColorPalette
Gold,
BlueGrey,
Grey
};
];
}
@@ -1,4 +1,4 @@
namespace Daybreak.Models;
namespace Daybreak.Shared.Models;
public enum ColorScheme
{
@@ -1,6 +1,6 @@
using System.Windows.Media;
namespace Daybreak.Models;
namespace Daybreak.Shared.Models;
public sealed class ColoredTextElement
{
@@ -0,0 +1,8 @@
using Daybreak.Shared.Models.Builds;
namespace Daybreak.Shared.Models;
public sealed class DownloadedBuild
{
public string? PreferredName { get; set; }
public IBuildEntry? Build { get; set; }
}
@@ -1,6 +1,6 @@
using System;
namespace Daybreak.Models;
namespace Daybreak.Shared.Models;
public sealed class ElevationRequest
{
+16
View File
@@ -0,0 +1,16 @@
using Daybreak.Shared.Models.Guildwars;
using System.ComponentModel;
using System.Windows.Extensions;
namespace Daybreak.Models;
public partial class EventViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
[GenerateNotifyPropertyChanged]
private Event? seasonalEvent;
[GenerateNotifyPropertyChanged]
private bool active;
[GenerateNotifyPropertyChanged]
private bool upcoming;
}
+20
View File
@@ -0,0 +1,20 @@
using System.ComponentModel;
namespace Daybreak.Shared.Models;
public sealed class ExecutablePath : INotifyPropertyChanged
{
private string path = string.Empty;
public event PropertyChangedEventHandler? PropertyChanged;
public string Path
{
get => this.path;
set
{
this.path = value;
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.Path)));
}
}
}
@@ -1,4 +1,4 @@
namespace Daybreak.Models;
namespace Daybreak.Shared.Models;
public enum ExecutionPolicies
{
@@ -0,0 +1,12 @@
using Daybreak.Shared.Models.Guildwars;
using Daybreak.Shared.Models.LaunchConfigurations;
namespace Daybreak.Shared.Models.FocusView;
/// <summary>
/// XD Name
/// </summary>
internal sealed class PlayerContextMenuContext
{
public GuildWarsApplicationLaunchContext? GuildWarsApplicationLaunchContext { get; set; }
public PlayerInformation? Player { get; set; }
}
@@ -1,6 +1,6 @@
using Daybreak.Models.Guildwars;
using Daybreak.Shared.Models.Guildwars;
namespace Daybreak.Models.FocusView;
namespace Daybreak.Shared.Models.FocusView;
public sealed class QuestEntry : QuestLogEntry
{
@@ -1,6 +1,6 @@
using Daybreak.Models.Guildwars;
using Daybreak.Shared.Models.Guildwars;
namespace Daybreak.Models.FocusView;
namespace Daybreak.Shared.Models.FocusView;
public sealed class QuestLocationEntry : QuestLogEntry
{
public override string Title { get; init; } = string.Empty;
@@ -1,4 +1,4 @@
namespace Daybreak.Models.FocusView;
namespace Daybreak.Shared.Models.FocusView;
public abstract class QuestLogEntry
{
@@ -1,4 +1,4 @@
namespace Daybreak.Models.FocusView;
namespace Daybreak.Shared.Models.FocusView;
public sealed class QuestLogSeparator : QuestLogEntry
{
public override string Title { get; init; } = string.Empty;
@@ -1,6 +1,6 @@
using Newtonsoft.Json;
namespace Daybreak.Models.Github;
namespace Daybreak.Shared.Models.Github;
public sealed class GithubRefTag
{
@@ -0,0 +1,10 @@
using Daybreak.Shared.Models.Progress;
using System.Threading;
namespace Daybreak.Shared.Models;
public sealed class GuildWarsUpdateRequest
{
public string? ExecutablePath { get; init; }
public GuildwarsInstallationStatus? Status { get; init; }
public CancellationToken CancellationToken { get; init; }
}
@@ -0,0 +1,6 @@
namespace Daybreak.Shared.Models;
public sealed class GuildWarsUpdateResponse
{
public bool Result { get; init; }
public string? ExecutablePath { get; init; }
}
@@ -1,54 +1,57 @@
using System;
using Daybreak.Shared.Converters;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Daybreak.Models.Guildwars;
namespace Daybreak.Shared.Models.Guildwars;
[JsonConverter(typeof(AttributeJsonConverter))]
public sealed class Attribute
{
public static Attribute FastCasting { get; } = new() { Name = "Fast Casting", Id = 0, Profession = Profession.Mesmer };
public static Attribute IllusionMagic { get; } = new() { Name = "Illusion Magic", Id = 1, Profession = Profession.Mesmer };
public static Attribute DominationMagic { get; } = new() { Name = "Domination Magic", Id = 2, Profession = Profession.Mesmer };
public static Attribute InspirationMagic { get; } = new() { Name = "Inspiration Magic", Id = 3, Profession = Profession.Mesmer };
public static Attribute BloodMagic { get; } = new() { Name = "Blood Magic", Id = 4, Profession = Profession.Necromancer };
public static Attribute DeathMagic { get; } = new() { Name = "Death Magic", Id = 5, Profession = Profession.Necromancer };
public static Attribute SoulReaping { get; } = new() { Name = "Soul Reaping", Id = 6, Profession = Profession.Necromancer };
public static Attribute Curses { get; } = new() { Name = "Curses", Id = 7, Profession = Profession.Necromancer };
public static Attribute AirMagic { get; } = new() { Name = "Air Magic", Id = 8, Profession = Profession.Elementalist };
public static Attribute EarthMagic { get; } = new() { Name = "Earth Magic", Id = 9, Profession = Profession.Elementalist };
public static Attribute FireMagic { get; } = new() { Name = "Fire Magic", Id = 10, Profession = Profession.Elementalist };
public static Attribute WaterMagic { get; } = new() { Name = "Water Magic", Id = 11, Profession = Profession.Elementalist };
public static Attribute EnergyStorage { get; } = new() { Name = "Energy Storage", Id = 12, Profession = Profession.Elementalist };
public static Attribute HealingPrayers { get; } = new() { Name = "Healing Prayers", Id = 13, Profession = Profession.Monk };
public static Attribute SmitingPrayers { get; } = new() { Name = "Smiting Prayers", Id = 14, Profession = Profession.Monk };
public static Attribute ProtectionPrayers { get; } = new() { Name = "Protection Prayers", Id = 15, Profession = Profession.Monk };
public static Attribute DivineFavor { get; } = new() { Name = "Divine Favor", Id = 16, Profession = Profession.Monk };
public static Attribute Strength { get; } = new() { Name = "Strength", Id = 17, Profession = Profession.Warrior };
public static Attribute AxeMastery { get; } = new() { Name = "Axe Mastery", Id = 18, Profession = Profession.Warrior };
public static Attribute HammerMastery { get; } = new() { Name = "Hammer Mastery", Id = 19, Profession = Profession.Warrior };
public static Attribute Swordsmanship { get; } = new() { Name = "Swordsmanship", Id = 20, Profession = Profession.Warrior };
public static Attribute Tactics { get; } = new() { Name = "Tactics", Id = 21, Profession = Profession.Warrior };
public static Attribute BeastMastery { get; } = new() { Name = "Beast Mastery", Id = 22, Profession = Profession.Ranger };
public static Attribute Expertise { get; } = new() { Name = "Expertise", Id = 23, Profession = Profession.Ranger };
public static Attribute WildernessSurvival { get; } = new() { Name = "Wilderness Survival", Id = 24, Profession = Profession.Ranger };
public static Attribute Marksmanship { get; } = new() { Name = "Marksmanship", Id = 25, Profession = Profession.Ranger };
public static Attribute DaggerMastery { get; } = new() { Name = "Dagger Mastery", Id = 29, Profession = Profession.Assassin };
public static Attribute DeadlyArts { get; } = new() { Name = "Deadly Arts", Id = 30, Profession = Profession.Assassin };
public static Attribute ShadowArts { get; } = new() { Name = "Shadow Arts", Id = 31, Profession = Profession.Assassin };
public static Attribute Communing { get; } = new() { Name = "Communing", Id = 32, Profession = Profession.Ritualist };
public static Attribute RestorationMagic { get; } = new() { Name = "Restoration Magic", Id = 33, Profession = Profession.Ritualist };
public static Attribute ChannelingMagic { get; } = new() { Name = "Channeling Magic", Id = 34, Profession = Profession.Ritualist };
public static Attribute CriticalStrikes { get; } = new() { Name = "Critical Strikes", Id = 35, Profession = Profession.Assassin };
public static Attribute SpawningPower { get; } = new() { Name = "Spawning Power", Id = 36, Profession = Profession.Ritualist };
public static Attribute SpearMastery { get; } = new() { Name = "Spear Mastery", Id = 37, Profession = Profession.Paragon };
public static Attribute Command { get; } = new() { Name = "Command", Id = 38, Profession = Profession.Paragon };
public static Attribute Motivation { get; } = new() { Name = "Motivation", Id = 39, Profession = Profession.Paragon };
public static Attribute Leadership { get; } = new() { Name = "Leadership", Id = 40, Profession = Profession.Paragon };
public static Attribute ScytheMastery { get; } = new() { Name = "Scythe Mastery", Id = 41, Profession = Profession.Dervish };
public static Attribute WindPrayers { get; } = new() { Name = "Wind Prayers", Id = 42, Profession = Profession.Dervish };
public static Attribute EarthPrayers { get; } = new() { Name = "Earth Prayers", Id = 43, Profession = Profession.Dervish };
public static Attribute Mysticism { get; } = new() { Name = "Mysticism", Id = 44, Profession = Profession.Dervish };
public static IEnumerable<Attribute> Attributes { get; } = new List<Attribute>
public static readonly Attribute FastCasting = new() { Name = "Fast Casting", Id = 0, Profession = Profession.Mesmer };
public static readonly Attribute IllusionMagic = new() { Name = "Illusion Magic", Id = 1, Profession = Profession.Mesmer };
public static readonly Attribute DominationMagic = new() { Name = "Domination Magic", Id = 2, Profession = Profession.Mesmer };
public static readonly Attribute InspirationMagic = new() { Name = "Inspiration Magic", Id = 3, Profession = Profession.Mesmer };
public static readonly Attribute BloodMagic = new() { Name = "Blood Magic", Id = 4, Profession = Profession.Necromancer };
public static readonly Attribute DeathMagic = new() { Name = "Death Magic", Id = 5, Profession = Profession.Necromancer };
public static readonly Attribute SoulReaping = new() { Name = "Soul Reaping", Id = 6, Profession = Profession.Necromancer };
public static readonly Attribute Curses = new() { Name = "Curses", Id = 7, Profession = Profession.Necromancer };
public static readonly Attribute AirMagic = new() { Name = "Air Magic", Id = 8, Profession = Profession.Elementalist };
public static readonly Attribute EarthMagic = new() { Name = "Earth Magic", Id = 9, Profession = Profession.Elementalist };
public static readonly Attribute FireMagic = new() { Name = "Fire Magic", Id = 10, Profession = Profession.Elementalist };
public static readonly Attribute WaterMagic = new() { Name = "Water Magic", Id = 11, Profession = Profession.Elementalist };
public static readonly Attribute EnergyStorage = new() { Name = "Energy Storage", Id = 12, Profession = Profession.Elementalist };
public static readonly Attribute HealingPrayers = new() { Name = "Healing Prayers", Id = 13, Profession = Profession.Monk };
public static readonly Attribute SmitingPrayers = new() { Name = "Smiting Prayers", Id = 14, Profession = Profession.Monk };
public static readonly Attribute ProtectionPrayers = new() { Name = "Protection Prayers", Id = 15, Profession = Profession.Monk };
public static readonly Attribute DivineFavor = new() { Name = "Divine Favor", Id = 16, Profession = Profession.Monk };
public static readonly Attribute Strength = new() { Name = "Strength", Id = 17, Profession = Profession.Warrior };
public static readonly Attribute AxeMastery = new() { Name = "Axe Mastery", Id = 18, Profession = Profession.Warrior };
public static readonly Attribute HammerMastery = new() { Name = "Hammer Mastery", Id = 19, Profession = Profession.Warrior };
public static readonly Attribute Swordsmanship = new() { Name = "Swordsmanship", Id = 20, Profession = Profession.Warrior };
public static readonly Attribute Tactics = new() { Name = "Tactics", Id = 21, Profession = Profession.Warrior };
public static readonly Attribute BeastMastery = new() { Name = "Beast Mastery", Id = 22, Profession = Profession.Ranger };
public static readonly Attribute Expertise = new() { Name = "Expertise", Id = 23, Profession = Profession.Ranger };
public static readonly Attribute WildernessSurvival = new() { Name = "Wilderness Survival", Id = 24, Profession = Profession.Ranger };
public static readonly Attribute Marksmanship = new() { Name = "Marksmanship", Id = 25, Profession = Profession.Ranger };
public static readonly Attribute DaggerMastery = new() { Name = "Dagger Mastery", Id = 29, Profession = Profession.Assassin };
public static readonly Attribute DeadlyArts = new() { Name = "Deadly Arts", Id = 30, Profession = Profession.Assassin };
public static readonly Attribute ShadowArts = new() { Name = "Shadow Arts", Id = 31, Profession = Profession.Assassin };
public static readonly Attribute Communing = new() { Name = "Communing", Id = 32, Profession = Profession.Ritualist };
public static readonly Attribute RestorationMagic = new() { Name = "Restoration Magic", Id = 33, Profession = Profession.Ritualist };
public static readonly Attribute ChannelingMagic = new() { Name = "Channeling Magic", Id = 34, Profession = Profession.Ritualist };
public static readonly Attribute CriticalStrikes = new() { Name = "Critical Strikes", Id = 35, Profession = Profession.Assassin };
public static readonly Attribute SpawningPower = new() { Name = "Spawning Power", Id = 36, Profession = Profession.Ritualist };
public static readonly Attribute SpearMastery = new() { Name = "Spear Mastery", Id = 37, Profession = Profession.Paragon };
public static readonly Attribute Command = new() { Name = "Command", Id = 38, Profession = Profession.Paragon };
public static readonly Attribute Motivation = new() { Name = "Motivation", Id = 39, Profession = Profession.Paragon };
public static readonly Attribute Leadership = new() { Name = "Leadership", Id = 40, Profession = Profession.Paragon };
public static readonly Attribute ScytheMastery = new() { Name = "Scythe Mastery", Id = 41, Profession = Profession.Dervish };
public static readonly Attribute WindPrayers = new() { Name = "Wind Prayers", Id = 42, Profession = Profession.Dervish };
public static readonly Attribute EarthPrayers = new() { Name = "Earth Prayers", Id = 43, Profession = Profession.Dervish };
public static readonly Attribute Mysticism = new() { Name = "Mysticism", Id = 44, Profession = Profession.Dervish };
public static readonly IEnumerable<Attribute> Attributes = new List<Attribute>
{
FastCasting,
IllusionMagic,
@@ -137,6 +140,7 @@ public sealed class Attribute
public int Id { get; private set; }
public string? Name { get; private set; }
public Profession? Profession { get; private set; }
public override string ToString() => this.Name ?? string.Empty;
private Attribute()
{
}
+13
View File
@@ -0,0 +1,13 @@
using System.Collections.Generic;
using Daybreak.Shared.Models.Builds;
namespace Daybreak.Shared.Models.Guildwars;
public sealed class Build
{
public BuildMetadata? BuildMetadata { get; set; }
public Profession Primary { get; set; } = Profession.None;
public Profession Secondary { get; set; } = Profession.None;
public List<AttributeEntry> Attributes { get; set; } = [];
public List<Skill> Skills { get; set; } = [Skill.NoSkill, Skill.NoSkill, Skill.NoSkill, Skill.NoSkill, Skill.NoSkill, Skill.NoSkill, Skill.NoSkill, Skill.NoSkill];
}
@@ -0,0 +1,125 @@
using Daybreak.Shared.Models.Builds;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
namespace Daybreak.Shared.Models.Guildwars;
public abstract class BuildEntryBase : INotifyPropertyChanged, IBuildEntry
{
public event PropertyChangedEventHandler? PropertyChanged;
public Dictionary<string, string>? Metadata { get; set; }
public string? PreviousName { get; set; }
public int? ToolboxBuildId
{
get
{
if (this.Metadata?.TryGetValue(nameof(this.ToolboxBuildId), out var toolBoxBuildString) is true &&
int.TryParse(toolBoxBuildString, out var toolboxBuild))
{
return toolboxBuild;
}
return default;
}
set
{
this.Metadata ??= [];
this.Metadata[nameof(this.ToolboxBuildId)] = value.HasValue ? value.Value.ToString() : string.Empty;
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.ToolboxBuildId)));
}
}
public bool IsToolboxBuild
{
get
{
if (this.Metadata?.TryGetValue(nameof(this.IsToolboxBuild), out var toolBoxBuildString) is true &&
bool.TryParse(toolBoxBuildString, out var toolboxBuild))
{
return toolboxBuild;
}
return false;
}
set
{
this.Metadata ??= [];
this.Metadata[nameof(this.IsToolboxBuild)] = value.ToString();
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.IsToolboxBuild)));
}
}
public DateTimeOffset CreationTime
{
get
{
if (this.Metadata?.TryGetValue(nameof(this.CreationTime), out var creationTimeString) is true &&
int.TryParse(creationTimeString, out var creationTimeUnix))
{
return DateTimeOffset.FromUnixTimeSeconds(creationTimeUnix);
}
return DateTimeOffset.MinValue;
}
set
{
this.Metadata ??= [];
this.Metadata[nameof(this.CreationTime)] = value.ToUniversalTime().ToUnixTimeSeconds().ToString();
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.CreationTime)));
}
}
public string? Name
{
get;
set
{
field = value;
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.Name)));
}
}
public string? SourceUrl
{
get
{
if (this.Metadata?.TryGetValue(nameof(this.SourceUrl), out var sourceUrl) is true)
{
return sourceUrl;
}
return default;
}
set
{
this.Metadata ??= [];
this.Metadata[nameof(this.SourceUrl)] = value ?? string.Empty;
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.SourceUrl)));
}
}
public List<PartyCompositionMetadataEntry>? PartyComposition
{
get
{
if (this.Metadata?.TryGetValue(nameof(this.PartyComposition), out var serializedPartyComposition) is true &&
!string.IsNullOrWhiteSpace(serializedPartyComposition))
{
return JsonConvert.DeserializeObject<List<PartyCompositionMetadataEntry>>(serializedPartyComposition);
}
return default;
}
set
{
this.Metadata ??= [];
this.Metadata[nameof(PartyCompositionMetadataEntry)] = value is null
? string.Empty
: JsonConvert.SerializeObject(value, Formatting.None);
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(this.PartyComposition)));
}
}
protected virtual void OnPropertyChanged(string propertyName)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
@@ -1,6 +1,6 @@
using System.Collections.Generic;
namespace Daybreak.Models.Guildwars;
namespace Daybreak.Shared.Models.Guildwars;
public sealed class BuildMetadata
{
@@ -16,7 +16,7 @@ public sealed class BuildMetadata
public int SkillsLength { get; set; }
public bool TailPresent { get; set; }
public bool NewTemplate { get; set; }
public List<int> SkillIds { get; set; } = new();
public List<int> AttributesIds { get; set; } = new();
public List<int> AttributePoints { get; set; } = new();
public List<int> SkillIds { get; set; } = [];
public List<int> AttributesIds { get; set; } = [];
public List<int> AttributePoints { get; set; } = [];
}
@@ -1,9 +1,12 @@
using System;
using Daybreak.Shared.Converters;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Daybreak.Models.Guildwars;
namespace Daybreak.Shared.Models.Guildwars;
[JsonConverter(typeof(CampaignJsonConverter))]
public sealed class Campaign
{
public static Campaign Core { get; } = new()
@@ -1,9 +1,12 @@
using System;
using Daybreak.Shared.Converters;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Daybreak.Models.Guildwars;
namespace Daybreak.Shared.Models.Guildwars;
[JsonConverter(typeof(ContinentJsonConverter))]
public sealed class Continent
{
public static Continent Tyria { get; } = new Continent
+169
View File
@@ -0,0 +1,169 @@
using System;
using System.Collections.Generic;
namespace Daybreak.Shared.Models.Guildwars;
/// <summary>
/// Seasonal holidays and in-game events, as retrieved from https://www.guildwars.com/en/events.
/// All events begin and end at 12pm UTC-7
/// </summary>
public sealed class Event
{
public static readonly Event WintersdayJanuary = new()
{
Title = "Wintersday",
Description = "See towns glimmering with festive décor, deliver presents to needy little urchins, defeat the scheming Grentches, and spread Wintersday cheer to your fellow Tyrians! The fun culminates with a grand finale that runs every three hours on January 1!",
WikiUrl = "https://wiki.guildwars.com/wiki/Wintersday",
From = new DateOnly(1, 1, 1),
To = new DateOnly(1, 1, 2)
};
public static readonly Event CanthanNewYear = new()
{
Title = "Canthan New Year",
Description = "Join the people of Cantha as they prepare a heavenly feast to honor the Celestial Animal of the coming year! This annual week-long celebration features Canthan cuisine, festive fireworks, special prizes, and the famed Shing Jea Boardwalk!",
WikiUrl = "https://wiki.guildwars.com/wiki/Canthan_New_Year",
From = new DateOnly(1, 1, 31),
To = new DateOnly(1, 2, 7)
};
public static readonly Event LuckyTreatsWeek = new()
{
Title = "Lucky Treats Week",
Description = "Shamrock Ale and Four-Leaf Clovers will be dropping throughout Tyria! Go fast, adventurers, and gather all the green you can before this special week ends!",
WikiUrl = "https://wiki.guildwars.com/wiki/Lucky_Treats_Week",
From = new DateOnly(1, 3, 14),
To = new DateOnly(1, 3, 21)
};
public static readonly Event SweetTreatsWeek = new()
{
Title = "Sweet Treats Week",
Description = "Sweet Treats Week is upon us, which means its time to load up on springtime goodies. Chocolate Bunnies and Golden Eggs will be randomly mixed in with regular drops all across Tyria. Get hopping!",
WikiUrl = "https://wiki.guildwars.com/wiki/Sweet_Treats_Week",
From = new DateOnly(1, 4, 10),
To = new DateOnly(1, 4, 17)
};
public static readonly Event AnniversaryCelebration = new()
{
Title = "Guild Wars Anniversary Celebration",
Description = "Guild Wars is another year older and the party just won't stop! Strap on your party hats, unpack your fireworks, and get ready to celebrate!",
WikiUrl = "https://wiki.guildwars.com/wiki/Anniversary_Celebration",
From = new DateOnly(1, 4, 22),
To = new DateOnly(1, 5, 6)
};
public static readonly Event DragonFestival = new()
{
Title = "Dragon Festival",
Description = "The Dragon Festival is almost upon us and Cantha is ready to roll out the red carpet. Time to stock up on bottle rockets, gorge on red bean cakes, and collect enough victory tokens for your pick of festival hats.",
WikiUrl = "https://wiki.guildwars.com/wiki/Dragon_Festival",
From = new DateOnly(1, 6, 27),
To = new DateOnly(1, 7, 4)
};
public static readonly Event WintersdayInJuly = new()
{
Title = "Wintersday In July",
Description = "Just can't wait til Wintersday? Jump into a mini version of Tyrias famed winter celebration! Stock up on seasonal treats or target your friends in the Snowball Arena during this week-long celebration.",
WikiUrl = "https://wiki.guildwars.com/wiki/Wintersday_in_July",
From = new DateOnly(1, 7, 24),
To = new DateOnly(1, 7, 31)
};
public static readonly Event WayfarersReverie = new()
{
Title = "Wayfarer's Reverie",
Description = "The spirit of adventure beckons to you! Its time to seek out the festival coordinator on each continent and start a quest to prove your adventuring prowess. Collect enough evidence of your travels and receive a special gift!",
WikiUrl = "https://wiki.guildwars.com/wiki/Wayfarer%27s_Reverie",
From = new DateOnly(1, 8, 25),
To = new DateOnly(1, 9, 1)
};
public static readonly Event PirateWeek = new()
{
Title = "Pirate Week",
Description = "Avast! This seafaring celebration will have NPCs in Lions Arch and Kamadan talking like salty sea dogs. Join in the fun or walk the plank. Yarr!",
WikiUrl = "https://wiki.guildwars.com/wiki/Pirate_Week",
From = new DateOnly(1, 9, 13),
To = new DateOnly(1, 9, 20)
};
public static readonly Event BreastCancerAwarenessMonth = new()
{
Title = "Breast Cancer Awareness Month",
Description = "Sadie Salvitas arrives in Lions Arch on October 1 and will be selling vials of pink dye throughout the month in support of Breast Cancer Awareness.",
WikiUrl = "https://wiki.guildwars.com/wiki/Login_screen_announcements/Archive#Breast_Cancer_Awareness_Month",
From = new DateOnly(1, 10, 1),
To = new DateOnly(1, 11, 2)
};
public static readonly Event Halloween = new()
{
Title = "Halloween",
Description = "Get ready for two whole weeks of mischief and mayhem in Tyria, courtesy of Mad King Thorn and his Lunatic Court. The madness escalates to the final event on October 31, when the Mad King himself appears every three hours—join if you dare!",
WikiUrl = "https://wiki.guildwars.com/wiki/Halloween",
From = new DateOnly(1, 10, 18),
To = new DateOnly(1, 11, 2)
};
public static readonly Event SpecialTreatsWeek = new()
{
Title = "Special Treats Week",
Description = "It's time for special, seasonal delights such as Slices of Pumpkin Pie and Hard Apple Cider to begin to drop all over Tyria. Gather what you can, but don't stuff yourself; Wintersday is just around the corner!",
WikiUrl = "https://wiki.guildwars.com/wiki/Special_Treats_Week",
From = new DateOnly(1, 11, 21),
To = new DateOnly(1, 11, 28)
};
public static readonly Event WintersdayDecember = new()
{
Title = "Wintersday",
Description = "See towns glimmering with festive décor, deliver presents to needy little urchins, defeat the scheming Grentches, and spread Wintersday cheer to your fellow Tyrians! The fun culminates with a grand finale that runs every three hours on January 1!",
WikiUrl = "https://wiki.guildwars.com/wiki/Wintersday",
From = new DateOnly(1, 12, 19),
To = new DateOnly(1, 12, 31)
};
public static readonly Event AprilFoolsDay = new()
{
Title = "April Fools' Day",
Description = "*CLASSIFIED INFORMATION*\r\nTGlzdGVuLC Bhbm Qgd W5kZXJz dG FuZC4g VG hhd CBBbm5 paG lsYXRv c iBnb 2xlbSBp cyBvdXQ gd Ghlcm UuIEl0 IGN hb id0IG JlIGJ h cmdh aW5lZ CB3 aX RoL iBJdCBj YW4n d CBiZ SByZWF zb25lZ C B3aX RoLi BJd C Bkb2 Vzbid0I GZlZWwgcGl 0eS wgb3 I gcmVtb3Jz ZSwg b3I gZmV hci4g QW5 kIGl 0IGFi c2 9s dXRl bHk gd2lsbC Bub 3Qgc 3RvcC wgZX Zlc iwg dW50aW w gU2Fy YWggY W5kIE d3Z W4 gYXJ lIGRl YWQu",
WikiUrl = "https://wiki.guildwars.com/wiki/April_Fools%27_Day",
From = new DateOnly(1, 4, 1),
To = new DateOnly(1, 4, 2)
};
public static readonly IEnumerable<Event> Events =
[
WintersdayJanuary,
CanthanNewYear,
LuckyTreatsWeek,
AprilFoolsDay,
SweetTreatsWeek,
AnniversaryCelebration,
DragonFestival,
WintersdayInJuly,
WayfarersReverie,
PirateWeek,
BreastCancerAwarenessMonth,
Halloween,
SpecialTreatsWeek,
WintersdayDecember
];
public string? Title { get; set; }
public string? Description { get; set; }
public string? WikiUrl { get; set; }
public DateOnly From { get; set; }
public DateOnly To { get; set; }
private Event()
{
}
}
+135
View File
@@ -0,0 +1,135 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace Daybreak.Shared.Models.Guildwars;
public sealed class Hero : IWikiEntity
{
public static readonly Hero None = new() { Id = 0, Profession = Profession.None };
public static readonly Hero Norgu = new() { Id = 1, Name = "Norgu", WikiUrl = "https://wiki.guildwars.com/wiki/Norgu", Profession = Profession.Mesmer };
public static readonly Hero Goren = new() { Id = 2, Name = "Goren", WikiUrl = "https://wiki.guildwars.com/wiki/Goren", Profession = Profession.Warrior };
public static readonly Hero Tahlkora = new() { Id = 3, Name = "Tahlkora", WikiUrl = "https://wiki.guildwars.com/wiki/Tahlkora", Profession = Profession.Monk };
public static readonly Hero MasterOfWhispers = new() { Id = 4, Name = "Master of Whispers", WikiUrl = "https://wiki.guildwars.com/wiki/Master_of_Whispers", Profession = Profession.Necromancer };
public static readonly Hero AcolyteJin = new() { Id = 5, Name = "Acolyte Jin", WikiUrl = "https://wiki.guildwars.com/wiki/Acolyte_Jin", Profession = Profession.Ranger };
public static readonly Hero Koss = new() { Id = 6, Name = "Koss", WikiUrl = "https://wiki.guildwars.com/wiki/Koss", Profession = Profession.Warrior };
public static readonly Hero Dunkoro = new() { Id = 7, Name = "Dunkoro", WikiUrl = "https://wiki.guildwars.com/wiki/Dunkoro", Profession = Profession.Monk };
public static readonly Hero AcolyteSousuke = new() { Id = 8, Name = "Acolyte Sousuke", WikiUrl = "https://wiki.guildwars.com/wiki/Acolyte_Sousuke", Profession = Profession.Elementalist };
public static readonly Hero Melonni = new() { Id = 9, Name = "Melonni", WikiUrl = "https://wiki.guildwars.com/wiki/Melonni", Profession = Profession.Dervish };
public static readonly Hero ZhedShadowhoof = new() { Id = 10, Name = "Zhed Shadowhoof", WikiUrl = "https://wiki.guildwars.com/wiki/Zhed_Shadowhoof", Profession = Profession.Elementalist };
public static readonly Hero GeneralMorgahn = new() { Id = 11, Name = "General Morgahn", WikiUrl = "https://wiki.guildwars.com/wiki/General_Morgahn", Profession = Profession.Paragon };
public static readonly Hero MagridTheSly = new() { Id = 12, Name = "Magrid the Sly", WikiUrl = "https://wiki.guildwars.com/wiki/Magrid_the_Sly", Profession = Profession.Ranger };
public static readonly Hero Zenmai = new() { Id = 13, Name = "Zenmai", WikiUrl = "https://wiki.guildwars.com/wiki/Zenmai", Profession = Profession.Assassin };
public static readonly Hero Olias = new() { Id = 14, Name = "Olias", WikiUrl = "https://wiki.guildwars.com/wiki/Olias", Profession = Profession.Necromancer };
public static readonly Hero Razah = new() { Id = 15, Name = "Razah", WikiUrl = "https://wiki.guildwars.com/wiki/Razah", Profession = Profession.None };
public static readonly Hero MOX = new() { Id = 16, Name = "M.O.X.", WikiUrl = "https://wiki.guildwars.com/wiki/M.O.X.", Profession = Profession.Dervish };
public static readonly Hero KeiranThackeray = new() { Id = 17, Name = "Keiran Thackeray", WikiUrl = "https://wiki.guildwars.com/wiki/Keiran_Thackeray", Profession = Profession.Paragon };
public static readonly Hero Jora = new() { Id = 18, Name = "Jora", WikiUrl = "https://wiki.guildwars.com/wiki/Jora", Profession = Profession.Warrior };
public static readonly Hero PyreFierceshot = new() { Id = 19, Name = "Pyre Fierceshot", WikiUrl = "https://wiki.guildwars.com/wiki/Pyre_Fierceshot", Profession = Profession.Ranger };
public static readonly Hero Anton = new() { Id = 20, Name = "Anton", WikiUrl = "https://wiki.guildwars.com/wiki/Anton", Profession = Profession.Assassin };
public static readonly Hero Livia = new() { Id = 21, Name = "Livia", WikiUrl = "https://wiki.guildwars.com/wiki/Livia", Profession = Profession.Necromancer };
public static readonly Hero Hayda = new() { Id = 22, Name = "Hayda", WikiUrl = "https://wiki.guildwars.com/wiki/Hayda", Profession = Profession.Paragon };
public static readonly Hero Kahmu = new() { Id = 23, Name = "Kahmu", WikiUrl = "https://wiki.guildwars.com/wiki/Kahmu", Profession = Profession.Dervish };
public static readonly Hero Gwen = new() { Id = 24, Name = "Gwen", WikiUrl = "https://wiki.guildwars.com/wiki/Gwen", Profession = Profession.Mesmer };
public static readonly Hero Xandra = new() { Id = 25, Name = "Xandra", WikiUrl = "https://wiki.guildwars.com/wiki/Xandra", Profession = Profession.Ritualist };
public static readonly Hero Vekk = new() { Id = 26, Name = "Vekk", WikiUrl = "https://wiki.guildwars.com/wiki/Vekk", Profession = Profession.Elementalist };
public static readonly Hero OgdenStonehealer = new() { Id = 27, Name = "Ogden Stonehealer", WikiUrl = "https://wiki.guildwars.com/wiki/Ogden_Stonehealer", Profession = Profession.Monk };
public static readonly Hero Merc1 = new() { Id = 28, Name = "Mercenary Hero 1", Profession = Profession.None };
public static readonly Hero Merc2 = new() { Id = 29, Name = "Mercenary Hero 2", Profession = Profession.None };
public static readonly Hero Merc3 = new() { Id = 30, Name = "Mercenary Hero 3", Profession = Profession.None };
public static readonly Hero Merc4 = new() { Id = 31, Name = "Mercenary Hero 4", Profession = Profession.None };
public static readonly Hero Merc5 = new() { Id = 32, Name = "Mercenary Hero 5", Profession = Profession.None };
public static readonly Hero Merc6 = new() { Id = 33, Name = "Mercenary Hero 6", Profession = Profession.None };
public static readonly Hero Merc7 = new() { Id = 34, Name = "Mercenary Hero 7", Profession = Profession.None };
public static readonly Hero Merc8 = new() { Id = 35, Name = "Mercenary Hero 8", Profession = Profession.None };
public static readonly Hero Miku = new() { Id = 36, Name = "Miku", WikiUrl = "https://wiki.guildwars.com/wiki/Miku", Profession = Profession.Assassin };
public static readonly Hero ZeiRi = new() { Id = 37, Name = "Zei Ri", WikiUrl = "https://wiki.guildwars.com/wiki/Zei_Ri", Profession = Profession.Ritualist };
public static readonly List<Hero> Heroes = [
None,
Norgu,
Goren,
Tahlkora,
MasterOfWhispers,
AcolyteJin,
Koss,
Dunkoro,
AcolyteSousuke,
Melonni,
ZhedShadowhoof,
GeneralMorgahn,
MagridTheSly,
Zenmai,
Olias,
Razah,
MOX,
KeiranThackeray,
Jora,
PyreFierceshot,
Anton,
Livia,
Hayda,
Kahmu,
Gwen,
Xandra,
Vekk,
OgdenStonehealer,
Merc1,
Merc2,
Merc3,
Merc4,
Merc5,
Merc6,
Merc7,
Merc8,
Miku,
ZeiRi
];
public static bool TryParse(int id, out Hero hero)
{
hero = Heroes.Where(n => n.Id == id).FirstOrDefault()!;
if (hero is null)
{
return false;
}
return true;
}
public static bool TryParse(string name, out Hero hero)
{
hero = Heroes.Where(n => n.Name == name).FirstOrDefault()!;
if (hero is null)
{
return false;
}
return true;
}
public static Hero Parse(int id)
{
if (TryParse(id, out var hero) is false)
{
throw new InvalidOperationException($"Could not find a hero with id {id}");
}
return hero;
}
public static Hero Parse(string name)
{
if (TryParse(name, out var hero) is false)
{
throw new InvalidOperationException($"Could not find a hero with name {name}");
}
return hero;
}
private Hero()
{
}
public int Id { get; init; }
public string? Name { get; init; }
public string? WikiUrl { get; init; }
public required Profession Profession { get; init; }
}
@@ -1,4 +1,4 @@
namespace Daybreak.Models.Guildwars;
namespace Daybreak.Shared.Models.Guildwars;
public interface IIconUrlEntity
{
@@ -1,4 +1,4 @@
namespace Daybreak.Models.Guildwars;
namespace Daybreak.Shared.Models.Guildwars;
public interface IItemModHash
{
@@ -1,4 +1,4 @@
namespace Daybreak.Models.Guildwars;
namespace Daybreak.Shared.Models.Guildwars;
public interface IWikiEntity
{
@@ -1,6 +1,6 @@
using System.Collections.Generic;
namespace Daybreak.Models.Guildwars;
namespace Daybreak.Shared.Models.Guildwars;
public sealed class Inscription : ItemBase, IWikiEntity, IIconUrlEntity
{
@@ -10,12 +10,12 @@ public sealed class Inscription : ItemBase, IWikiEntity, IIconUrlEntity
public static readonly Inscription FocusOrShieldInscription = new() { Id = 15541, Name = "Focus Items or Shields Inscription", WikiUrl = "https://wiki.guildwars.com/wiki/Inscription", IconUrl = "https://wiki.guildwars.com/images/6/61/Inscription_focus_items_or_shields.png" };
public static IReadOnlyList<Inscription> Inscriptions { get; } = new List<Inscription>
{
public static IReadOnlyList<Inscription> Inscriptions { get; } =
[
WeaponInscription,
FocusInscription,
FocusOrShieldInscription
};
];
public string? WikiUrl { get; init; }
@@ -1,4 +1,4 @@
namespace Daybreak.Models.Guildwars;
namespace Daybreak.Shared.Models.Guildwars;
public enum InstanceType
{
@@ -1,8 +1,12 @@
using System;
using Daybreak.Shared.Converters;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Daybreak.Models.Guildwars;
namespace Daybreak.Shared.Models.Guildwars;
[JsonConverter(typeof(ItemBaseJsonConverter))]
public abstract class ItemBase
{
public static IReadOnlyCollection<ItemBase> AllItems { get; } = Enumerable.Empty<ItemBase>()
@@ -10,6 +14,7 @@ public abstract class ItemBase
.Concat(Material.All)
.Concat(Inscription.Inscriptions)
.Concat(Rune.Runes)
.Concat(VialOfDye.Vials)
.ToList();
public static bool TryParse<T>(int id, IEnumerable<ItemModifier>? modifiers, out T item)
@@ -82,7 +87,7 @@ public abstract class ItemBase
i.Modifiers is not null)
{
return i.Modifiers.Count() == modifiers.Count() &&
i.Modifiers.All(modifiers.Contains);
i.Modifiers.All(i1 => modifiers.Any(i2 => i1.Modifier == i2.Modifier));
}
else if (i.Modifiers is not null)
{
@@ -125,7 +130,7 @@ public abstract class ItemBase
throw new InvalidOperationException($"Could not find a item with name {name}");
}
return item;
return item!;
}
private static ItemBase? FilterAndFirstOrDefault(Func<ItemBase, bool> filter) => AllItems
@@ -1,4 +1,4 @@
namespace Daybreak.Models.Guildwars;
namespace Daybreak.Shared.Models.Guildwars;
public readonly struct ItemModifier
{
public uint Modifier { get; init; }
@@ -0,0 +1,7 @@
namespace Daybreak.Shared.Models.Guildwars;
public sealed class LoginData
{
public string Email { get; init; } = string.Empty;
public string PlayerName { get; init; } = string.Empty;
}
@@ -1,4 +1,4 @@
namespace Daybreak.Models.Guildwars;
namespace Daybreak.Shared.Models.Guildwars;
public sealed class MainPlayerData
{
@@ -1,25 +1,26 @@
using System.Collections.Generic;
namespace Daybreak.Models.Guildwars;
namespace Daybreak.Shared.Models.Guildwars;
public sealed class MainPlayerInformation : IEntity
public sealed class MainPlayerInformation
{
public string? Name { get; init; }
public uint Timer { get; init; }
public TitleInformation? TitleInformation { get; init; }
public int Id { get; init; }
public int Level { get; init; }
public Position? Position { get; init; }
public Position? Position { get; set; }
public Profession? PrimaryProfession { get; init; }
public Profession? SecondaryProfession { get; init; }
public List<Profession>? UnlockedProfession { get; init; }
public Build? CurrentBuild { get; init; }
public float CurrentHealth { get; init; }
public float CurrentHealth { get; set; }
public float MaxHealth { get; init; }
public float CurrentEnergy { get; init; }
public float CurrentEnergy { get; set; }
public float MaxEnergy { get; init; }
public float HealthRegen { get; init; }
public float EnergyRegen { get; init; }
public float RotationAngle { get; set; }
public bool HardModeUnlocked { get; init; }
public uint Experience { get; init; }
public uint Morale { get; init; }
@@ -1,9 +1,12 @@
using System;
using Daybreak.Shared.Converters;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Daybreak.Models.Guildwars;
namespace Daybreak.Shared.Models.Guildwars;
[JsonConverter(typeof(MapJsonConverter))]
public sealed class Map : IWikiEntity
{
public int Id { get; private set; }
@@ -253,6 +256,7 @@ public sealed class Map : IWikiEntity
public static readonly Map DwaynaVsGrenth = new() { Id = 253, Name = "Dwayna Vs Grenth", WikiUrl = "https://wiki.guildwars.com/wiki/Dwayna_Vs_Grenth" };
public static readonly Map SunjiangDistrictExplorable = new() { Id = 254, Name = "Sunjiang District", WikiUrl = "https://wiki.guildwars.com/wiki/Sunjiang_District" };
public static readonly Map NahpuiQuarterExplorable = new() { Id = 257, Name = "Nahpui Quarter", WikiUrl = "https://wiki.guildwars.com/wiki/Nahpui_Quarter" };
public static readonly Map NahpuiQuarterExplorable2 = new() { Id = 265, Name = "Nahpui Quarter", WikiUrl = "https://wiki.guildwars.com/wiki/Nahpui_Quarter" };
public static readonly Map UrgozsWarren = new() { Id = 266, Name = "Urgozs Warren", WikiUrl = "https://wiki.guildwars.com/wiki/Urgozs_Warren" };
public static readonly Map TahnnakaiTempleExplorable = new() { Id = 267, Name = "Tahnnakai Temple", WikiUrl = "https://wiki.guildwars.com/wiki/Tahnnakai_Temple" };
public static readonly Map AltrummRuins = new() { Id = 270, Name = "Altrumm Ruins", WikiUrl = "https://wiki.guildwars.com/wiki/Altrumm_Ruins" };
@@ -352,6 +356,7 @@ public sealed class Map : IWikiEntity
public static readonly Map YohlonHavenOutpost = new() { Id = 381, Name = "Yohlon Haven", WikiUrl = "https://wiki.guildwars.com/wiki/Yohlon_Haven" };
public static readonly Map GandaraTheMoonFortress = new() { Id = 382, Name = "Gandara", WikiUrl = "https://wiki.guildwars.com/wiki/Gandara" };
public static readonly Map TheFloodplainOfMahnkelon = new() { Id = 383, Name = "The Floodplain of Mahnkelon", WikiUrl = "https://wiki.guildwars.com/wiki/The_Floodplain_of_Mahnkelon" };
public static readonly Map TheFloodplainOfMahnkelon2 = new() { Id = 384, Name = "The Floodplain of Mahnkelon", WikiUrl = "https://wiki.guildwars.com/wiki/The_Floodplain_of_Mahnkelon" };
public static readonly Map LionsArchSunspearsinKryta = new() { Id = 385, Name = "Lion's Arch", WikiUrl = "https://wiki.guildwars.com/wiki/Lion's_Arch" };
public static readonly Map TuraisProcession = new() { Id = 386, Name = "Turai's Procession", WikiUrl = "https://wiki.guildwars.com/wiki/Turai's_Procession" };
public static readonly Map SunspearSanctuaryOutpost = new() { Id = 387, Name = "Sunspear Sanctuary", WikiUrl = "https://wiki.guildwars.com/wiki/Sunspear_Sanctuary" };
@@ -378,6 +383,7 @@ public sealed class Map : IWikiEntity
public static readonly Map TheKodashBazaarOutpost = new() { Id = 414, Name = "The Kodash Bazaar", WikiUrl = "https://wiki.guildwars.com/wiki/The_Kodash_Bazaar" };
public static readonly Map LionsGate = new() { Id = 415, Name = "Lion's Gate", WikiUrl = "https://wiki.guildwars.com/wiki/Lion's_Gate" };
public static readonly Map TheMirrorOfLyss = new() { Id = 416, Name = "The Mirror of Lyss", WikiUrl = "https://wiki.guildwars.com/wiki/The_Mirror_of_Lyss" };
public static readonly Map TheMirrorOfLyss2 = new() { Id = 419, Name = "The Mirror of Lyss", WikiUrl = "https://wiki.guildwars.com/wiki/The_Mirror_of_Lyss" };
public static readonly Map SecuretheRefuge = new() { Id = 420, Name = "Secure the Refuge", WikiUrl = "https://wiki.guildwars.com/wiki/Secure_the_Refuge" };
public static readonly Map VentaCemetery = new() { Id = 421, Name = "Venta Cemetery", WikiUrl = "https://wiki.guildwars.com/wiki/Venta_Cemetery" };
public static readonly Map KamadanJewelOfIstanExplorable = new() { Id = 422, Name = "Kamadan", WikiUrl = "https://wiki.guildwars.com/wiki/Kamadan" };
@@ -491,6 +497,7 @@ public sealed class Map : IWikiEntity
public static readonly Map DajkahInlet = new() { Id = 554, Name = "Dajkah Inlet", WikiUrl = "https://wiki.guildwars.com/wiki/Dajkah_Inlet" };
public static readonly Map TheShadowNexus = new() { Id = 555, Name = "The Shadow Nexus", WikiUrl = "https://wiki.guildwars.com/wiki/The_Shadow_Nexus" };
public static readonly Map SparkflySwamp = new() { Id = 556, Name = "Sparkfly Swamp", WikiUrl = "https://wiki.guildwars.com/wiki/Sparkfly_Swamp" };
public static readonly Map SparkflySwamp2 = new() { Id = 558, Name = "Sparkfly Swamp", WikiUrl = "https://wiki.guildwars.com/wiki/Sparkfly_Swamp" };
public static readonly Map GateOftheNightfallenLandsOutpost = new() { Id = 559, Name = "Gate of the Nightfallen Lands", WikiUrl = "https://wiki.guildwars.com/wiki/Gate_of_the_Nightfallen_Lands" };
public static readonly Map CathedralofFlamesLevel1 = new() { Id = 560, Name = "Cathedral of Flames", WikiUrl = "https://wiki.guildwars.com/wiki/Cathedral_of_Flames" };
public static readonly Map TheTroubledKeeper = new() { Id = 561, Name = "Gate of Torment", WikiUrl = "https://wiki.guildwars.com/wiki/Gate_of_Torment" };
@@ -1053,6 +1060,7 @@ public sealed class Map : IWikiEntity
YohlonHavenOutpost,
GandaraTheMoonFortress,
TheFloodplainOfMahnkelon,
TheFloodplainOfMahnkelon2,
LionsArchSunspearsinKryta,
TuraisProcession,
SunspearSanctuaryOutpost,
@@ -1079,6 +1087,7 @@ public sealed class Map : IWikiEntity
TheKodashBazaarOutpost,
LionsGate,
TheMirrorOfLyss,
TheMirrorOfLyss2,
SecuretheRefuge,
VentaCemetery,
KamadanJewelOfIstanExplorable,
@@ -1192,6 +1201,7 @@ public sealed class Map : IWikiEntity
DajkahInlet,
TheShadowNexus,
SparkflySwamp,
SparkflySwamp2,
GateOftheNightfallenLandsOutpost,
CathedralofFlamesLevel1,
TheTroubledKeeper,

Some files were not shown because too many files have changed in this diff Show More