Compare commits

...
294 Commits
Author SHA1 Message Date
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
amacocianandGitHub bca9f6d66b Fix loading screen flickering (#295)
* Fix loading screen flickering

* Increment version
2023-06-29 15:01:41 +00:00
amacocianandGitHub d6f71cb2eb Performance improvements (#293)
Ability to disable minimap
Closes #291
Fix main player health/energy proper values
Better granularity for memory access
Focus view uses less memory footprint to gather necesarry resources
2023-06-29 13:38:28 +00:00
amacocianandGitHub 986d09867c Cache duplication fix (#292)
* Cache duplication fix
Performance improvement
Closes #290

* Increment version
2023-06-29 10:08:00 +02:00
amacocianandGitHub 97cb2151f9 Memory reader cache to better control memory access (#289)
Expand guildwars locations, campaign, continent
Make bloogum use image cache
Make bloogum show images based on character location
Link Campaign -> Continent -> Region -> Map
2023-06-28 15:32:19 +00:00
amacocianandGitHub 338ac100a1 Realm of torment npcs (#288) 2023-06-27 16:55:44 +00:00
amacocianandGitHub 01badcee6a More nightfall npcs (#287) 2023-06-27 11:26:25 +00:00
amacocianandGitHub 302cf1114c Fix bug with trader messages options (#286)
Reorder options
2023-06-26 19:05:13 +00:00
amacocianandGitHub 613e03dc75 High def skill icons (#284)
* Use high-definition skill icons

* Increment version
2023-06-26 17:42:38 +00:00
amacocianandGitHub 4267359cb2 DSOAL support (#282)
Reworked mod support
2023-06-26 13:16:29 +00:00
amacocianandGitHub daac8ec787 More nightfall npcs (#281)
Fixes for quests and npcs
UTs for quests, npcs and items
2023-06-26 10:00:17 +00:00
amacocianandGitHub 857adec459 More vabbian npcs (#280)
* More vabbian npcs

* Increment version
2023-06-23 08:50:56 +00:00
amacocianandGitHub b46e10a1a6 Vabbian npcs (#279) 2023-06-22 12:50:18 +00:00
amacocianandGitHub 10799b7e9c Fix modifiers view (#278)
Show modifiers for unknown items
Fix enemy drawing
Added some npcs
2023-06-21 20:19:44 +00:00
amacocianandGitHub 6bbeaa1738 More Kournan npcs (#277) 2023-06-21 17:36:43 +00:00
amacocianandGitHub 1a0f1cbf9a Performance improvements to images (#275) 2023-06-21 09:20:23 +00:00
amacocianandGitHub 68e708fe96 Price history improvements (#274)
Inventory view improvements
Base for inscriptions
Base for runes
2023-06-20 00:32:28 +00:00
amacocianandGitHub a2166f2327 Add Guild Hall npcs (#272) 2023-06-18 15:24:23 +00:00
amacocianandGitHub 6d55366bdc Mark unknown entities with a question mark (#271) 2023-06-18 11:58:39 +00:00
amacocianandGitHub 28fcaa81cf Installer fix (#270)
Closes #269
2023-06-17 18:52:01 +00:00
amacocianandGitHub c5efc2990e Guildwars copy service (#268)
Fix one focus view bug
2023-06-17 14:18:35 +02:00
amacocianandGitHub 597010b9a1 Memory reader base pointer fixes (#267)
Installer fixes
2023-06-16 16:17:20 +00:00
amacocianandGitHub 1f71816256 Make regex trade searches case-insensitive (#264) 2023-06-16 13:09:37 +00:00
amacocianandGitHub 7c3618d2b5 Trade alerts (#263)
Notifications improvements
2023-06-16 11:06:18 +00:00
amacocianandGitHub df9038039c Highlight color specific trading words (#262) 2023-06-09 10:13:36 +00:00
amacocianandGitHub 9a4b23976a Release v56 (#259)
Inventory Component toggle
Fix inventory component visibility
Inventory component performance improvements
2023-06-08 21:33:13 +00:00
amacocianandGitHub 8732e0fe5e Release v55 (#256)
Sounds
Split FocusView into components
Focus view inventory component
Notifications view
Internet connectivity
2023-06-08 19:58:26 +00:00
amacocianandGitHub c23b84c4d5 Improve pathfinding algorithm (#255)
Improve minimap color contrasts
2023-06-01 20:56:49 +00:00
amacocianandGitHub 345b6a792a Color coded boss icons based on primary profession (#254) 2023-05-30 22:00:00 +00:00
amacocianandGitHub d9ae52165d Show npc profession in context menu (#252) 2023-05-30 20:54:03 +00:00
amacocianandGitHub 4f40e8328b Release v51 (#251)
* Release v51
Fixes duplicate npcs
Adds npcs for all games
Improve focus view memory reading latency
Clean up metrics
Closes #202
Closes #203
Closes #201

* Small fixes
2023-05-30 17:08:25 +00:00
amacocianandGitHub ebdd828b06 Improve the price chart date visibility (#250) 2023-05-22 18:49:41 +00:00
amacocianandGitHub 711acb55db Release v49 (#249)
Cache loaded images to improve performance
Separate quotes from trade views
Implement price history view
Local price history database
Fix notification popups
Fix icon caching

Closes #248
Closes #247
Closes #246
Closes #245
2023-05-19 20:08:43 +00:00
amacocianandGitHub 7dfc21bfe0 Setup NotificationService (#244)
Separate price quotes from trades
2023-05-16 20:05:28 +00:00
amacocianandGitHub 78644a6eec Add Flag and Person minimap icons (#242) 2023-05-15 20:41:11 +00:00
amacocianandGitHub 30b1d77575 Implement trade chat views (#239)
More UI improvements
Much better IconCache implementation
Re-enable screen selector
2023-05-15 17:55:25 +00:00
amacocianandGitHub a9626d03a4 Update README.md (#238)
Signed-off-by: Macocian Alexandru Victor <amacocian@yahoo.com>
2023-05-14 20:57:05 +02:00
amacocianandGitHub be731bbffb Unify UI buttons (#237)
* Unify UI buttons
Use Theme Accent as highlight
Fix browser concurrency issues
Fix browser enable/disable during runtime
Unify button sizes and looks

Closes #235
Closes #236

* Increment version
2023-05-10 20:35:24 +00:00
amacocianandGitHub 8cd40e2de3 Dynamic Options View (#234)
Import MahApps Metro
2023-05-08 18:52:10 +00:00
amacocianandGitHub 7745594bb6 Draw engagement area for party (#233)
Clean uMod installation
Closes #232
Closes #220
2023-05-07 13:07:37 +00:00
amacocianandGitHub e43bedf1c2 Fix auto-load template procedure (#229)
Fix character name loading on guildwars startup
Closes #126
2023-05-03 21:22:32 +00:00
amacocianandGitHub d6623a8646 Automatically add downloaded tpfs to mod list (#228)
* Automatically add downloaded tpfs to mod list
Closes #227

* Increment version
2023-05-03 16:33:25 +00:00
amacocianandGitHub 403ba51a7d Add possibility to download tpf files from the uMod browser page (#226)
* Add possibility to download tpf files from the uMod browser page
* Organize menu by sections
* Limit logs to improve performance
* Fix screenmanageroptions name
* Fix focusview default webpage
2023-05-03 15:04:40 +00:00
amacocianandGitHub b185a606e6 Integrate with mods (#223)
* Integrate with GWToolboxpp and uMod
* Separate configuration into multiple extensible parts
* Generalize downloading service
2023-05-03 11:10:18 +00:00
amacocianandGitHub 342a9a4826 Add more minimap icons (#221)
Support for team colored icons
2023-05-01 11:36:22 +00:00
amacocianandGitHub 2df2e8a65e Added support for multi-color SVG icons (#219) 2023-04-30 16:04:09 +00:00
amacocianandGitHub 2d5e9231a9 Minimap improvements (#217)
Map icons have overload for minimum size
Pathfinding now finds paths even when start/end points are not on the map
Map can now draw SVGs
2023-04-30 12:31:11 +00:00
amacocianandGitHub 818e2bf1d0 Drawing bugfixes (#210) 2023-04-10 18:47:03 +02:00
amacocianandGitHub f0a876f7cc Rework minimap drawing (#208)
Setup extensible drawing modules
2023-04-10 13:57:35 +00:00
amacocianandGitHub 3fae8f91cb Add support for map icons (#207)
Add res-shrine icons to minimap
2023-04-09 20:26:15 +00:00
amacocianandGitHub 8b08056ca7 Show targeted npc details (#206) 2023-04-09 18:30:25 +00:00
amacocianandGitHub 39eaf53deb Setup startup actions (#204)
Rename temp installer on startup
2023-04-09 16:21:11 +00:00
amacocianandGitHub 4674d1d7e5 Add support for npc types and names (#200)
* Introduce npcs and support for npc names

* Update version
2023-04-07 10:34:11 +00:00
amacocianandGitHub b8b5cc8b1d Optimize pathfinding (#198)
* Optimize pathfinding
Simplified initial search to no longer take distance into account
Metrics for pathfinding

* Increment version
2023-04-05 15:30:48 +00:00
amacocianandGitHub dc987233a7 Retry pathfinding loading on failure (#197) 2023-04-04 21:35:16 +00:00
amacocianandGitHub 266b400c22 Pathfinding v1 (#196)
* Pathfinding algorithm for minimap

* Fix adjacency lists

* Better adjancency list generation

* Improve pathfinding algorithm

* Some other tries

* Pathfinding algorithm for minimap

* Fix adjacency lists

* Better adjancency list generation

* Improve pathfinding algorithm

* Some other tries

* Improvements to the minimap and pathing

* Improve pathfinder

* Draw path forests

* Implement working pathfinding solution
2023-04-04 20:43:14 +00:00
amacocianandGitHub a4ac083fd0 General client improvements (#195)
Hit-target for off-screen quest markers
Save window position on every move instead of only on closing
2023-04-03 20:21:12 +00:00
amacocianandGitHub 320dd16838 Show objective direction for loaded quests (#194) 2023-04-02 19:22:17 +00:00
amacocianandGitHub 5c05c636bc Add quest marker functionality to the minimap (#192) 2023-04-02 14:57:49 +00:00
amacocianandGitHub 7103a8a83a Show party member context (#190)
Fix one Map id
2023-03-25 18:30:29 +00:00
amacocianandGitHub ad749d801a Minimap improvements (#189)
Closes #187
Closes #188

Minimap performance improvements
Add context menues for main player and living entities
2023-03-25 08:36:15 +00:00
amacocianandGitHub 747e9a0490 Minimap improvements (#186)
Closes #185
Closes #184
Closes #183
Show player information when right clicking on minimap
Allow minimap fullscreen
Decouple scrolling from memory reading frequency
Ignore task cancelled exceptions
2023-03-24 22:39:52 +00:00
amacocianandGitHub 836402bd0f Draw player position history on the minimap (#182) 2023-03-21 15:19:25 +00:00
amacocianandGitHub a3d5e1ce1f Add another check for corrupted images (#181)
* Add another check for corrupted images

* Check validity of icons on startup
Improve screen position saving
2023-03-21 08:45:22 +00:00
f2cc59a4ab Daybreak 0.9.8.18 (#179)
* Minimap implementation

* Fix minimap

* Add debounce logic to entities positions

* Cleanup

* Fix x64 build memory reading
Move build to x64
Fix entity debouncing
Added some backstops to prevent reading corrupted memory

* Add minimap zooming and panning functionality
Add main window position saving procedure

* Increment version

---------

Co-authored-by: Alex Macocian <amacocian@hotmail.com>
2023-03-20 21:38:53 +02:00
amacocianandGitHub 6ea77f7e05 Bugfixes and improvements (#176)
Closes #175
Closes #174
Closes #173
2023-03-09 19:53:28 +00:00
amacocianandGitHub 5ea8df7cb9 Bugfixes to memory reader (#172) 2023-03-08 20:17:58 +00:00
amacocianandGitHub c70e8ec90d Implement Guildwars downloader (#171) 2023-03-08 13:24:14 +00:00
amacocianandGitHub 210e3a8cb1 Add title data to memory retrieval (#169)
Add metrics for diagnostics
Add metrics view
2023-03-07 17:20:20 +00:00
amacocianandGitHub a0c3bb094c Performance improvements (#168)
* Performance improvements and bugfixes

* Increment version

* Better builds links

* Unify loading widget size
2023-03-05 08:55:21 +01:00
amacocianandGitHub b4d932692a Reduce words in FocusView character line (#167) 2023-03-04 17:18:03 +00:00
amacocianandGitHub 667534a07a Fix version parsing (#166) 2023-03-04 18:06:53 +01:00
amacocianandGitHub 159928f24b Integrate builds with Focus view (#164)
* Integrate builds with Focus view
Detect when GameData is invalid
Detect when reading memory is faulty
Show current character data in Focus View
Closes #161
Closes #162
Closes #163

* Increment version

* Bugfix version comparison script
2023-03-04 17:21:08 +01:00
amacocianandGitHub 8a91ded610 Fix buildtemplate skill removal (#160)
Closes #159
2023-03-03 22:28:27 +00:00
amacocianandGitHub 4226b7eb32 Improve performance of buildtemplateview (#158) 2023-03-03 21:50:25 +00:00
amacocianandGitHub b61c99dd1c Fix build template failing to load secondary attributes (#157)
Improve build template handling logic
Add attribute points calculator
2023-03-03 20:51:03 +00:00
amacocianandGitHub 1ccb0d5334 Add map entry to FocusView (#155)
Fix Icon Downloader
Improve settings navigation
Change multiple views to match the design of the rest of the application
2023-03-02 20:11:00 +01:00
amacocianandGitHub 7fa01353dd UX Bugfixes and improvements (#151)
Fix memory reading issues when restarting the game
Fixed current energy and health retrieval and calculation
Added health and energy bars in focus view
Fixed focus view size calculation
Improved buildtemplate performance
Improved buildtemplate navigation
Added loading widgets to menus that are loading asynchronously
2023-03-02 16:49:00 +00:00
amacocianandGitHub 4f849d880b Ux improvements (#148)
Rearrange quest log layout
Fix some quest names
Fix some buttons ux
Mitigate issues when reading guildwars memory
2023-03-02 01:58:07 +00:00
amacocianandGitHub 4b60c96aad Closes #146 #145 (#147) 2023-03-02 00:39:52 +00:00
amacocianandGitHub a4dc0d65cf Implement Focus View (#144)
* Implement Focus View
Read extra information from guildwars

* Prever focusview browser from being disposed
2023-03-01 18:42:53 +00:00
amacocianandGitHub 85e017423f #142 - Fix Vanguard Quests Missing (#143)
Closes #142
2023-02-28 18:24:37 +00:00
amacocianandGitHub b38488937b Alexmacocian/gwca integration (#141)
Setup memory scanner
Setup Focus View
Scan for player information and show in the Focus View
Setup Quest parsing
2023-02-27 17:22:04 +01:00
amacocianandGitHub d291d5825a #125 - Setup onboarding flow (#133)
* #125 - Setup onboarding flow
Closes #125

* Fix MenuService logging
2023-02-03 15:27:06 +00:00
amacocianandGitHub 9d6162f65f #131 - Downgrade to .net6 (#132) 2023-02-02 20:50:35 +00:00
amacocianandGitHub f54ab42a92 #129 - Change hashing algorithm to SHA512 (#130) 2023-02-02 18:31:07 +00:00
amacocianandGitHub 78c8ae3e8f #127 - Introduce Nullable Support (#128) 2023-02-02 18:05:10 +00:00
amacocianandGitHub c64830c5b6 #123 #113 #105 Build Templates Improvements (#124) 2023-01-21 21:35:16 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
561c7cf7b1 Bump microsoft/setup-msbuild from 1.0.1 to 1.1.3 (#111)
Bumps [microsoft/setup-msbuild](https://github.com/microsoft/setup-msbuild) from 1.0.1 to 1.1.3.
- [Release notes](https://github.com/microsoft/setup-msbuild/releases)
- [Changelog](https://github.com/microsoft/setup-msbuild/blob/master/building-release.md)
- [Commits](https://github.com/microsoft/setup-msbuild/compare/v1.0.1...v1.1.3)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-09 15:22:44 +01:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2c6862de41 Bump coverlet.collector from 3.1.2 to 3.2.0 (#112)
Bumps [coverlet.collector](https://github.com/coverlet-coverage/coverlet) from 3.1.2 to 3.2.0.
- [Release notes](https://github.com/coverlet-coverage/coverlet/releases)
- [Commits](https://github.com/coverlet-coverage/coverlet/commits/v3.2.0)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-09 15:10:18 +01:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
69842cbadf Bump Microsoft.NET.Test.Sdk from 17.4.0-preview-20221003-03 to 17.4.0 (#116)
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.4.0-preview-20221003-03 to 17.4.0.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Commits](https://github.com/microsoft/vstest/compare/v17.4.0-preview-20221003-03...v17.4.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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-09 14:24:26 +01:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
c7327e7bb2 Bump Microsoft.NET.Test.Sdk (#108)
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.4.0-preview-20220726-02 to 17.4.0-preview-20221003-03.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Commits](https://github.com/microsoft/vstest/compare/v17.4.0-preview-20220726-02...v17.4.0-preview-20221003-03)

---
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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-11 10:18:44 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
de33ed7fc4 Bump actions/setup-dotnet from 2 to 3 (#107)
Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet) from 2 to 3.
- [Release notes](https://github.com/actions/setup-dotnet/releases)
- [Commits](https://github.com/actions/setup-dotnet/compare/v2...v3)

---
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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-11 10:09:29 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>amacocian
c99bb8d074 Bump Microsoft.Web.WebView2 from 1.0.1343.22 to 1.0.1370.28 (#109)
* Bump Microsoft.Web.WebView2 from 1.0.1343.22 to 1.0.1370.28

Bumps Microsoft.Web.WebView2 from 1.0.1343.22 to 1.0.1370.28.

---
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>

* Update daybreak 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>
2022-10-11 10:02:33 +00:00
amacocianandGitHub a98e54ebc6 Sync namespaces (#104) 2022-09-23 09:56:47 +00:00
amacocianandGitHub a832aa1925 Minor fixes (#102) 2022-09-21 13:55:37 +00:00
amacocianandGitHub c7eb5debcb Refresh access token (#100) 2022-09-20 11:46:36 +00:00
amacocianandGitHub 91f0cb4e31 Implement expandable menu view (#95) 2022-09-19 19:08:34 +00:00
amacocianandGitHub 5e8407a6ab Make main view maintain its state (#94)
* Make main view maintain its state

* Stop checking game state when mainview is not loaded
2022-09-15 17:05:30 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>amacocian
243c2c1536 Bump Microsoft.Extensions.Logging.Abstractions from 6.0.1 to 6.0.2 (#91)
* Bump Microsoft.Extensions.Logging.Abstractions from 6.0.1 to 6.0.2

Bumps [Microsoft.Extensions.Logging.Abstractions](https://github.com/dotnet/runtime) from 6.0.1 to 6.0.2.
- [Release notes](https://github.com/dotnet/runtime/releases)
- [Commits](https://github.com/dotnet/runtime/compare/v6.0.1...v6.0.2)

---
updated-dependencies:
- dependency-name: Microsoft.Extensions.Logging.Abstractions
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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

* Bump 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>
2022-09-15 14:34:21 +00:00
amacocianandGitHub 930aca4ffe Bump dependencies (#90)
Signed-off-by: Macocian Alexandru Victor <amacocian@yahoo.com>
2022-09-12 18:11:36 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
1639cabe8e Bump Slim from 1.7.3 to 1.8.1 (#86)
Bumps [Slim](https://github.com/AlexMacocian/Slim) from 1.7.3 to 1.8.1.
- [Release notes](https://github.com/AlexMacocian/Slim/releases)
- [Commits](https://github.com/AlexMacocian/Slim/commits)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-07 08:38:17 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
5961a57c5b Bump Microsoft.Web.WebView2 from 1.0.1293.44 to 1.0.1343.22 (#85)
Bumps Microsoft.Web.WebView2 from 1.0.1293.44 to 1.0.1343.22.

---
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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-09-07 10:29:18 +02:00
amacocianandGitHub 75d9bc6dec Add checkmark when builds are synchronized (#84) 2022-08-27 12:54:48 +00:00
amacocianandGitHub 4ccca32881 Build synchronization speedups (#82) 2022-08-27 12:15:21 +00:00
amacocianandGitHub a7f5d9dd96 Fix deletion error when installing (#80)
Signed-off-by: Macocian Alexandru Victor <amacocian@yahoo.com>
2022-08-25 20:55:01 +00:00
amacocianandGitHub c8ba125abc Allow individual uploads/downloads for backed up builds (#77) 2022-08-25 20:44:20 +00:00
amacocianandGitHub 7d290031f1 Alexmacocian/fix secret build (#76)
* Fix pre-build secret building action

* Update version
2022-08-22 22:10:18 +00:00
amacocianandGitHub 5220a8c7ac Run fixed CD pipeline (#75) 2022-08-22 21:31:58 +00:00
amacocianandGitHub 33e221f60f Fix secret generation for CD pipeline (#74) 2022-08-22 21:05:13 +00:00
amacocianandGitHub 7f77547c50 Add support for build backups (#73) 2022-08-22 20:30:10 +00:00
amacocianandGitHub c5964e33ac Setup support for secrets (#72) 2022-08-22 12:55:29 +00:00
amacocianandGitHub 1c6f3ec797 Make all browsers use BrowserData folder (#70)
* Make all browsers use BrowserData folder

* Increment version
2022-08-21 14:09:26 +00:00
amacocianandGitHub 8601f61739 Run CD pipeline only on code changes (#67) 2022-08-20 15:24:45 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
91bac0d50b Bump actions/setup-dotnet from 1 to 2 (#64)
Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet) from 1 to 2.
- [Release notes](https://github.com/actions/setup-dotnet/releases)
- [Commits](https://github.com/actions/setup-dotnet/compare/v1...v2)

---
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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-20 15:22:41 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
0bf03e0fb5 Bump Xotl/cool-github-releases from 1.1.2 to 1.1.7 (#65)
Bumps [Xotl/cool-github-releases](https://github.com/Xotl/cool-github-releases) from 1.1.2 to 1.1.7.
- [Release notes](https://github.com/Xotl/cool-github-releases/releases)
- [Commits](https://github.com/Xotl/cool-github-releases/compare/v1.1.2...v1.1.7)

---
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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-20 15:22:24 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>amacocian
81401178a5 Bump Microsoft.Web.WebView2 from 1.0.1264.42 to 1.0.1293.44 (#66)
* Bump Microsoft.Web.WebView2 from 1.0.1264.42 to 1.0.1293.44

Bumps Microsoft.Web.WebView2 from 1.0.1264.42 to 1.0.1293.44.

---
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>

* Bump Microsoft.Web.WebView2 from 1.0.1264.42 to 1.0.1293.44

Bumps Microsoft.Web.WebView2 from 1.0.1264.42 to 1.0.1293.44.

---
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>

* 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>
2022-08-20 15:19:17 +02:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
882357a8e5 Bump Microsoft.NET.Test.Sdk (#63)
Bumps [Microsoft.NET.Test.Sdk](https://github.com/microsoft/vstest) from 17.4.0-preview-20220707-01 to 17.4.0-preview-20220726-02.
- [Release notes](https://github.com/microsoft/vstest/releases)
- [Commits](https://github.com/microsoft/vstest/compare/v17.4.0-preview-20220707-01...v17.4.0-preview-20220726-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>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-20 13:18:22 +00:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
abf629c5c6 Bump actions/checkout from 2 to 3 (#62)
Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3.
- [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/v2...v3)

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-08-20 13:10:53 +00:00
amacocianandGitHub 758f9004cd Setup code owners (#61)
* Setup code owners

* Install .net6 on codeql pipeline

* Fix csproj

* Make version check only work when changing code files
2022-08-20 15:03:35 +02:00
amacocianandGitHub f174f8cbb3 Create dependabot.yml
Signed-off-by: Macocian Alexandru Victor <amacocian@yahoo.com>
2022-08-20 14:42:07 +02:00
amacocianandGitHub f2f6bde25d Create codeql-analysis.yml
Signed-off-by: Macocian Alexandru Victor <amacocian@yahoo.com>
2022-08-20 14:37:59 +02:00
amacocianandGitHub 85f378b303 Improve performance across builds and skills menus (#59)
Make buildtemplate load builds asynchronously
Make buildtemplateview load skills asynchronously
Improve search experience by making string matching be done asynchronously
Reduce memory footprint by virtualizing long skill list
2022-08-20 12:30:11 +00:00
amacocianandGitHub 71ab3fdefb Post-update actions (#57) 2022-08-19 12:45:07 +00:00
amacocianandGitHub 2f83d6c860 Delete browser cache on update (#56) 2022-08-18 20:17:36 +00:00
amacocianandGitHub 3db4975b48 Make launcher update the installer after an update (#55) 2022-08-18 19:59:08 +00:00
amacocianandGitHub 6a6eea5d02 Implement search bar for builds and skills (#50)
* Add search bars to builds and skills

* Fix search bar not appearing.
Improve search function.

* Increment version

* Rename version check so it can be added to status checks
2022-08-18 21:26:57 +02:00
amacocianandGitHub 8fe9eeb32f Icon downloader bugfixes (#47)
* Fix icon download to properly finish
2022-08-16 19:47:25 +02:00
amacocianandGitHub 4c1025243b Background Icon Downloader (#44)
* Download icons in the background

* Fix icon downloader browser setup
2022-08-16 17:51:35 +02:00
amacocianandGitHub f24eb02ca1 Pipeline to check that version is updated (#43)
* Pipeline to check that version is updated
2022-08-13 00:24:54 +02:00
amacocianandGitHub b01c09491f Download and check icons at startup (#41) 2022-08-12 23:41:22 +02:00
amacocianandGitHub 54ae742899 Increment version (#40) 2022-08-12 13:22:59 +02:00
amacocianandGitHub 4c862463d7 Fix IconRetriever (#38)
Use browser to bypass header issues with http client
2022-08-12 13:15:46 +02:00
amacocianandGitHub b455c89ddc Minor improvements (#36)
Deprecate Microsoft.Xaml.Behaviors.Wpf
Reverse version order in management view
2022-08-04 23:05:55 +02:00
amacocianandGitHub 782b76cd8e Remove admin mode when updating (#31) 2022-08-04 21:59:55 +02:00
amacocianandGitHub 230c2d9457 Setup executable installer (#29)
* Setup executable installer

* Increment update to 0.9.3

* Improve installer
2022-08-04 21:39:17 +02:00
amacocianandGitHub 63531e3b8c Hide console window (#25) 2022-08-04 19:52:54 +02:00
amacocianandGitHub ac430305f4 Update to .net 6 and update dependencies (#24)
* Update to .net 6 and update dependencies
2022-08-04 19:25:53 +02:00
amacocianandGitHub 3d830cfc16 Update dependencies (#23) 2021-07-10 13:39:00 +03:00
amacocianandGitHub b529aa8861 Fix logging on startup when ILogger is null (#22) 2021-07-10 12:45:44 +03:00
amacocianandGitHub 3798daa54e Update dependencies (#21)
* Update dependencies
* Minor nit fixes
* Fix UTs
2021-07-10 12:08:43 +03:00
amacocianandGitHub 624380ed86 Use IOptions instead of IConfigurationManager (#20)
* Use IOptions instead of dependency on IConfigurationManager
2021-06-22 15:48:37 +03:00
amacocianandGitHub 2b025e225b Updated wpfextended dependency 2021-06-11 13:50:58 +02:00
amacocianandGitHub 15a67ea28c Minor fixes
Stop showing browser when browser is disabled
Prevent setting address of browser when browser is disabled (should prevent browser from instantiating when disabled)
Ignore errors from browser caused by switching view before the browser could be initialized
Provide expression to filter logs
Button to export logs to json file
2021-06-07 14:33:54 +02:00
amacocianandGitHub c6b62fd5fd Logging improvements
Log uncaught exceptions
Logview expander
2021-06-07 00:34:43 +02:00
amacocianandGitHub 3c0877c1a0 Ability to keep a local cache of icons (#16) 2021-06-03 21:12:31 +02:00
967b57b9a8 Fix build code encoding/decoding view (#15)
Co-authored-by: Alexandru Macocian <almacoci@microsoft.com>
2021-06-03 20:40:56 +02:00
amacocianandGitHub f47cc319b5 Build template code field 2021-06-03 19:57:29 +02:00
amacocianandGitHub 26da84c4e7 Update to new version of wpfextended
Fix a bug where version parsing would ignore all 0s before the first digit
Remove LoggerFactory and LoggerProviders duplicated in WpfExtended
2021-06-03 14:48:35 +02:00
a39e8dc5c6 Separate CV from message (#12)
Co-authored-by: Alexandru Macocian <almacoci@microsoft.com>
2021-06-01 21:57:27 +02:00
1bb4669135 Introduce correlated logs (#11)
Co-authored-by: Alexandru Macocian <almacoci@microsoft.com>
2021-06-01 20:43:55 +02:00
amacocianandGitHub 0203eef006 Rework logging (#10)
* Rework log storing into a litedb.
LogView implementation to view logs.
Create crash.log on crash.

* Rename Logs namespace to Logging.
2021-05-18 19:49:51 +02:00
amacocianandGitHub 4ab50ee191 Use Microsoft.Logging.Abstractions
Typed ILogger.
2021-05-14 14:31:33 +02:00
amacocianandGitHub 06c1ec1ac2 Add scoped http client. (#8)
* Introduce scoped http client.
* Uts for scoped httpclient
2021-05-10 12:46:01 +02:00
amacocianandGitHub ef4befdc38 Version management view.
Enable/disable version autocheck.
Version management view.
2021-05-06 18:23:07 +02:00
amacocianandGitHub 33f49ddffa Cleanup cd pipeline (#6)
* Cleanup cd pipeline

* Remove cd pipeline on PR

* Cleanup CI pipeline comments.
2021-05-06 12:33:58 +02:00
amacocianandGitHub 49aa249b5b Generate changelog from last release tag.
Generate changelog from last release tag.
2021-05-05 23:01:57 +02:00
amacocianandGitHub c387d44890 Generate changelog from latest release.
Auto-generate changelog.
2021-05-05 21:31:45 +02:00
d4d09e7267 Update version (#3)
Co-authored-by: Alexandru Macocian <almacoci@microsoft.com>
2021-05-05 20:52:43 +02:00
amacocianandGitHub dd7bf02a97 Add CI & CD pipelines
Add CD&CI pipelines
2021-05-05 20:46:36 +02:00
Alexandru Macocian 6d0eeb478f Use source generator to generate dependency properties. 2021-05-05 17:23:37 +02:00
d4e9de48b1 Add ci pipeline (#1)
* Add ci pipeline

* Remove unused env variables.

* Change dotnet version to 5.0.5

* Change to dotnet 5.0.202

Co-authored-by: Alexandru Macocian <almacoci@microsoft.com>
2021-05-03 17:11:59 +02:00
Alexandru Macocian 6bd9877925 Remove dependency on InputSimulator. 2021-05-03 16:23:30 +02:00
Alexandru Macocian d38df6596f Remove keyboard macro functionality for now.
Unify input prompts.
Modify screenshot manager functionality to apply functionality of settings changed.
Update to 0.8.6.
2021-05-03 16:16:00 +02:00
Alexandru Macocian b4e31e859c Merge branch 'master' of https://github.com/AlexMacocian/Daybreak 2021-05-02 18:49:31 +02:00
Alexandru Macocian 1acd07c1be Change the way shortcut manager manages shortcuts.
Base for keyboard macros.
2021-05-02 18:49:25 +02:00
amacocianandGitHub b9b25bb098 Update README.md 2021-04-27 17:28:25 +02:00
amacocianandGitHub 5ea2981dc7 Update README.md 2021-04-27 17:25:03 +02:00
Alexandru Macocian 4fb96ca3a4 Ability to place screenshots in desired location. 2021-04-27 17:06:28 +02:00
Alexandru Macocian 6de52f5585 Ability to test placement while guildwars is running. 2021-04-26 11:26:43 +02:00
Alexandru Macocian 6622e41f64 Wait for guildwars window to be initialized before moving to desired window. 2021-04-26 11:02:23 +02:00
Alexandru Macocian 8405e4d1e5 Return to settings category after saving desired window. 2021-04-25 18:26:29 +02:00
Alexandru Macocian 0edc3f1560 Throw exception when screen id is invalid. 2021-04-25 18:24:51 +02:00
Alexandru Macocian c109fe7561 Ability to select on which window to place guildwars. 2021-04-25 18:20:45 +02:00
Alexandru Macocian b5413dca5c Include [Admin] tag when running as administrator. 2021-04-24 01:35:46 +02:00
Alexandru Macocian 6c2d4a1e70 No longer require administrator rights for normal usage.
Request elevation only in necesarry parts of the code.
Request elevation on update.
After update, launch application without elevation.
2021-04-24 01:20:36 +02:00
Alexandru Macocian be03f1a32d Run updates as admin 2021-04-23 23:37:01 +02:00
Alexandru Macocian 3ed1cc453a Implemented functionality to launch guildwars with lower privilege. 2021-04-23 20:24:28 +02:00
Alexandru Macocian 16030063ed Fix skill icon not unloading.
Moved all help icons on same side.
2021-04-23 19:52:09 +02:00
Alexandru Macocian 458696ad8f Fixed a bug where skill templates would try to load the image for No Skill.
Fixed a bug where build template manager would delete saved template.
2021-04-23 17:28:12 +02:00
Alexandru Macocian 6201702563 Skill holder now properly shows the top half of icons in the case where icons are bigger than normal. 2021-04-23 17:14:24 +02:00
Alexandru Macocian c5bea23a8f Make professions and attributes searchable.
Minor QOL changes to build view.
Handle exception caused by browser initialization getting canceled.
2021-04-23 16:59:31 +02:00
Alexandru Macocian e5f38f77ef Reverted html agility pack. 2021-04-23 11:40:05 +02:00
Alexandru Macocian 1d774ab8de Disable script injection when dynamic build loading is disabled.
Fixed a bug where earth prayers was not a recognized attribute.
2021-04-23 11:11:19 +02:00
Alexandru Macocian bc66ca9948 Feature flag to disable dynamic build loading in experimental settings. 2021-04-22 17:53:04 +02:00
amacocianandGitHub 524cd21fd4 Update README.md 2021-04-22 17:39:51 +02:00
amacocianandGitHub 132cb0e1f4 Update README.md 2021-04-22 17:32:35 +02:00
amacocianandGitHub 09c99e7731 Update README.md 2021-04-22 17:29:49 +02:00
Alexandru Macocian c9d0be1117 Update to 0.7.0 2021-04-22 17:02:48 +02:00
Alexandru Macocian 965055c8d7 Build management implementation.
Load build from browser when selection is detected to be a build template.
Load skill images from internet on demand.
Load skill details page when a skill is selected.
Separate skills on professions.
2021-04-22 17:02:28 +02:00
Alexandru Macocian f6bb21d0ef Build template parser and encoder.
Unit test project.
2021-04-20 20:06:15 +02:00
Alexandru Macocian 465e0a4ce0 Fix buttons while browser is fullscreen. 2021-04-20 12:51:26 +02:00
Alexandru Macocian 55f304b885 Update to wpfextended 0.2 2021-04-19 21:37:15 +02:00
Alexandru Macocian 0cb1d97332 Remove hyperlink from version text. 2021-04-17 20:04:20 +02:00
Alexandru Macocian e2091cd82f Home button for browsers.
Stop asking for updates if user already answered no.
2021-04-17 19:39:56 +02:00
Alexandru Macocian d2bada4159 Button to disable browsers. 2021-04-17 10:21:06 +02:00
Alexandru Macocian b27998d7f2 Basic support for texmod/umod. 2021-04-15 11:15:36 +02:00
amacocianandGitHub 98d3e21db9 Update README.md 2021-04-15 10:17:24 +02:00
Alexandru Macocian 0683504330 Minor gui fixes.
Set default webpages in application configuration.
Option to auto-launch gwtoolbox.
2021-04-15 09:57:19 +02:00
Alexandru Macocian 98bd1b2de6 Periodically check for updates.
Reorder settings in the settings category view.
2021-04-14 15:15:56 +02:00
Alexandru Macocian c169ca1684 Menu to manage guildwars executables. 2021-04-14 15:01:43 +02:00
Alexandru Macocian 88214ea166 Darken views with text to improve readability.
Better define the reason why guildwars failed to launch.
Auto set to default when adding first account.
Auto set another default when removing the default account.
2021-04-14 14:12:38 +02:00
Alexandru Macocian 4bdcd1a811 Changed version control to check all subversions. 2021-04-14 13:50:15 +02:00
Alexandru Macocian fa4f665a3e Fixed a bug with updating account details. 2021-04-13 21:28:49 +02:00
Alexandru Macocian e59e022c0a Updated to 0.5.0 2021-04-13 21:13:38 +02:00
Alexandru Macocian d096dc696a Multi-account management.
Split settings into multiple categories.
2021-04-13 21:09:41 +02:00
Alexandru Macocian 071007c3e5 Create application manifest.
Require highest available rights.
Return dialog message when registry is failed to be set.
2021-04-12 19:35:08 +02:00
Alexandru Macocian 57192d5043 Experimental multi-launch support 2021-04-12 19:09:00 +02:00
amacocianandGitHub 6af72683a8 Update README.md 2021-04-12 13:26:54 +02:00
amacocianandGitHub 3af9567506 Update README.md 2021-04-12 13:09:02 +02:00
Alexandru Macocian 1d7adf3944 Merge branch 'master' of https://github.com/AlexMacocian/Daybreak 2021-04-10 19:00:46 +02:00
Alexandru Macocian fb7399adf8 Add support for experimental features. 2021-04-10 19:00:39 +02:00
amacocianandGitHub 6ebbffdda1 Update README.md 2021-04-10 11:25:13 +02:00
Alexandru Macocian 2c35333cac Handle missing dependency on webview2 browser. 2021-04-10 11:18:46 +02:00
Alexandru Macocian fe5e38b216 Change update process to modify and restore execution policy before and after update.
Change update process to wait for the client to close instead of a static wait.
2021-04-10 10:31:36 +02:00
1041 changed files with 100592 additions and 3444 deletions
+137
View File
@@ -0,0 +1,137 @@
[*.cs]
# CA2254: Template should be a static expression
dotnet_diagnostic.CA2254.severity = none
csharp_indent_labels = one_less_than_current
csharp_using_directive_placement = outside_namespace:error
csharp_prefer_simple_using_statement = true:error
csharp_prefer_braces = true:silent
csharp_style_namespace_declarations = file_scoped:error
csharp_style_prefer_method_group_conversion = true:suggestion
csharp_style_expression_bodied_methods = false:silent
csharp_style_expression_bodied_constructors = false:silent
csharp_style_expression_bodied_operators = false:silent
csharp_style_expression_bodied_properties = true:silent
csharp_style_expression_bodied_indexers = true:silent
csharp_style_expression_bodied_accessors = true:silent
csharp_style_expression_bodied_lambdas = true:silent
csharp_style_expression_bodied_local_functions = false:silent
csharp_indent_braces = false
insert_final_newline = true
csharp_space_around_binary_operators = before_and_after
csharp_style_throw_expression = true:suggestion
csharp_style_prefer_null_check_over_type_check = true:suggestion
csharp_prefer_simple_default_expression = true:suggestion
csharp_style_prefer_local_over_anonymous_function = true:error
csharp_style_prefer_index_operator = true:suggestion
csharp_style_prefer_range_operator = true:suggestion
csharp_style_implicit_object_creation_when_type_is_apparent = true:suggestion
csharp_style_prefer_tuple_swap = true:suggestion
csharp_style_inlined_variable_declaration = true:suggestion
csharp_style_deconstructed_variable_declaration = true:error
csharp_style_unused_value_assignment_preference = discard_variable:error
csharp_style_unused_value_expression_statement_preference = discard_variable:silent
csharp_prefer_static_local_function = true:suggestion
csharp_style_allow_embedded_statements_on_same_line_experimental = true:silent
csharp_style_allow_blank_line_after_colon_in_constructor_initializer_experimental = true:silent
csharp_style_allow_blank_lines_between_consecutive_braces_experimental = false:suggestion
csharp_style_conditional_delegate_call = true:suggestion
csharp_style_prefer_parameter_null_checking = true:suggestion
csharp_style_prefer_switch_expression = true:suggestion
csharp_style_prefer_pattern_matching = true:silent
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
csharp_style_prefer_not_pattern = true:suggestion
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
csharp_style_prefer_extended_property_pattern = true:suggestion
csharp_style_var_for_built_in_types = false:silent
csharp_style_var_when_type_is_apparent = false:silent
csharp_style_var_elsewhere = false:silent
csharp_style_prefer_top_level_statements = true:suggestion
csharp_style_prefer_utf8_string_literals = true:suggestion
csharp_style_prefer_readonly_struct = true:suggestion
[*.{cs,vb}]
#### Naming styles ####
# Naming rules
dotnet_naming_rule.interface_should_be_begins_with_i.severity = error
dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
dotnet_naming_rule.types_should_be_pascal_case.severity = error
dotnet_naming_rule.types_should_be_pascal_case.symbols = types
dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = error
dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
# Symbol specifications
dotnet_naming_symbols.interface.applicable_kinds = interface
dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.interface.required_modifiers =
dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.types.required_modifiers =
dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
dotnet_naming_symbols.non_field_members.required_modifiers =
# Naming styles
dotnet_naming_style.begins_with_i.required_prefix = I
dotnet_naming_style.begins_with_i.required_suffix =
dotnet_naming_style.begins_with_i.word_separator =
dotnet_naming_style.begins_with_i.capitalization = pascal_case
dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case
dotnet_naming_style.pascal_case.required_prefix =
dotnet_naming_style.pascal_case.required_suffix =
dotnet_naming_style.pascal_case.word_separator =
dotnet_naming_style.pascal_case.capitalization = pascal_case
dotnet_style_operator_placement_when_wrapping = beginning_of_line
tab_width = 4
indent_size = 4
end_of_line = crlf
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:error
dotnet_style_prefer_auto_properties = true:error
dotnet_style_object_initializer = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
dotnet_style_prefer_conditional_expression_over_return = true:silent
dotnet_style_explicit_tuple_names = true:suggestion
dotnet_style_prefer_inferred_tuple_names = true:suggestion
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_compound_assignment = true:suggestion
dotnet_style_prefer_simplified_interpolation = true:suggestion
dotnet_style_namespace_match_folder = true:suggestion
dotnet_style_readonly_field = true:suggestion
dotnet_style_predefined_type_for_locals_parameters_members = true:silent
dotnet_style_predefined_type_for_member_access = true:silent
dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent
dotnet_style_allow_multiple_blank_lines_experimental = true:silent
dotnet_style_allow_statement_immediately_after_block_experimental = false:suggestion
dotnet_code_quality_unused_parameters = all:error
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:suggestion
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:suggestion
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:suggestion
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:suggestion
dotnet_style_qualification_for_field = true:error
dotnet_style_qualification_for_property = true:error
dotnet_style_qualification_for_method = true:error
dotnet_style_qualification_for_event = true:error
dotnet_diagnostic.CA1000.severity = error
[*.vb]
dotnet_diagnostic.CA1047.severity = error
+1
View File
@@ -0,0 +1 @@
* amacocian@yahoo.com
+16
View File
@@ -0,0 +1,16 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "github-actions" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "weekly"
- package-ecosystem: "nuget"
directory: "/"
schedule:
interval: "daily"
+118
View File
@@ -0,0 +1,118 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
# This continuous integration pipeline is triggered anytime a user pushes code to the repo.
# This pipeline builds the Wpf project, runs unit tests, then saves the MSIX build artifact.
name: Daybreak CD Pipeline
on:
push:
branches:
- master
paths:
- "Daybreak/**"
- "Daybreak.Installer/**"
workflow_dispatch:
jobs:
build:
strategy:
matrix:
targetplatform: [x86]
runs-on: windows-latest
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
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get Latest Tag
id: getLatestTag
uses: WyriHaximus/github-action-get-previous-tag@v1
- name: Generate changelog
id: gen_changelog
run: |
$changeLog = git log --no-merges --pretty="%h - %s (%an)<br />" ${{ env.LatestReleaseTag }}..HEAD
echo "::set-env name=Changelog::$changeLog"
env:
LatestReleaseTag: ${{steps.getLatestTag.outputs.tag}}
- name: Install .NET Core
uses: actions/setup-dotnet@v3
with:
dotnet-version: '7.x'
- name: Setup MSBuild.exe
uses: microsoft/setup-msbuild@v1.3.1
- name: Fetch submodules
run: |
git submodule update --init --recursive
- name: Build CMake Files
run: cmake -S . -B build -A Win32
- name: Setup project secrets
run: |
dotnet user-secrets --project Daybreak\Daybreak.csproj set AadApplicationId "${{ secrets.AadApplicationId }}"
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 --property:SolutionDir=$GITHUB_WORKSPACE
env:
RuntimeIdentifier: win-${{ matrix.targetplatform }}
- name: Build Daybreak project
run: dotnet build Daybreak -c $env:Configuration --property:SolutionDir=$env:GITHUB_WORKSPACE
- name: Set version variable
run: |
$version = .\Scripts\GetBuildVersion.ps1
echo "::set-env name=Version::$version"
- name: Create publish launcher files
run: dotnet publish .\Daybreak\Daybreak.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 installer files
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=true --self-contained true -o .\Publish
env:
RuntimeIdentifier: win-${{ matrix.targetplatform }}
- name: Pack publish files
run: |
Write-Host $env
.\Scripts\BuildRelease.ps1 -version $env:Version
shell: pwsh
- name: Publish release
uses: Xotl/cool-github-releases@v1.1.8
with:
mode: update
tag_name: v${{ env.Version }}
release_name: Daybreak v${{ env.Version }}
assets: .\Publish\daybreakv${{ env.Version }}.zip
github_token: ${{ env.GITHUB_TOKEN }}
replace_assets: true
body_mrkdwn: ${{ env.Changelog }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+60
View File
@@ -0,0 +1,60 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT license.
# This continuous integration pipeline is triggered anytime a user pushes code to the repo.
# This pipeline builds the Wpf project, runs unit tests, then saves the MSIX build artifact.
name: Daybreak CI Pipeline
on:
push:
branches:
- master
pull_request:
branches:
- master
jobs:
build:
strategy:
matrix:
targetplatform: [x86]
runs-on: windows-latest
env:
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
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install .NET Core
uses: actions/setup-dotnet@v3
with:
dotnet-version: '7.x'
- name: Setup MSBuild.exe
uses: microsoft/setup-msbuild@v1.3.1
- name: Fetch submodules
run: |
git submodule update --init --recursive
- name: Build CMake Files
run: cmake -S . -B build -A Win32
- name: Execute Unit Tests
run: dotnet test $env:Test_Project_Path --property:SolutionDir=$env:GITHUB_WORKSPACE
- 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 --property:SolutionDir=$env:GITHUB_WORKSPACE
env:
Configuration: Debug
RuntimeIdentifier: win-${{ matrix.targetplatform }}
+94
View File
@@ -0,0 +1,94 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"
on:
push:
branches: [ "master" ]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "master" ]
schedule:
- cron: '41 12 * * 6'
jobs:
analyze:
name: Analyze
runs-on: windows-latest
permissions:
actions: read
contents: read
security-events: write
strategy:
fail-fast: false
matrix:
language: [ 'csharp' ]
# 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
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Fetch submodules
run: |
git submodule update --init --recursive
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# 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
with:
dotnet-version: '7.x'
#- 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
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
# - run: |
# 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
+55
View File
@@ -0,0 +1,55 @@
name: Daybreak Version Check
on:
pull_request:
branches:
- master
paths:
- "Daybreak/**"
- "Daybreak.Installer/**"
jobs:
check_version:
strategy:
matrix:
targetplatform: [x86]
runs-on: windows-latest
env:
Configuration: Release
Solution_Path: Daybreak.sln
Actions_Allow_Unsecure_Commands: true
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Get Latest Tag
id: getLatestTag
uses: WyriHaximus/github-action-get-previous-tag@v1
- name: Fetch submodules
run: |
git submodule update --init --recursive
- name: Build CMake Files
run: cmake -S . -B build -A Win32
- name: Build Daybreak project
run: dotnet build Daybreak -c $env:Configuration --property:SolutionDir=$env:GITHUB_WORKSPACE
- name: Set version variable
run: |
$version = .\Scripts\GetBuildVersion.ps1
echo "::set-env name=Version::$version"
- name: Check version difference
run: |
.\Scripts\CompareVersions -currentVersion ${{ env.Version }} -lastVersion ${{ env.LatestReleaseTag }}
env:
LatestReleaseTag: ${{ steps.getLatestTag.outputs.tag }}
+2
View File
@@ -9,6 +9,7 @@
*.user
*.userosscache
*.sln.docstates
*.version
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
@@ -27,6 +28,7 @@ x86/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
build/
[Bb]in/
[Oo]bj/
[Oo]ut/
+3
View File
@@ -0,0 +1,3 @@
[submodule "GWCA"]
path = GWCA
url = https://github.com/GregLando113/GWCA
+16
View File
@@ -0,0 +1,16 @@
# CMakeList.txt : Top-level CMake project file, do global configuration
# and include sub-projects here.
#
cmake_minimum_required (VERSION 3.8)
# Enable Hot Reload for MSVC compilers if supported.
if (POLICY CMP0141)
cmake_policy(SET CMP0141 NEW)
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<IF:$<AND:$<C_COMPILER_ID:MSVC>,$<CXX_COMPILER_ID:MSVC>>,$<$<CONFIG:Debug,RelWithDebInfo>:EditAndContinue>,$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>>")
endif()
project ("Daybreak")
# Include sub-projects.
add_subdirectory ("Daybreak.GWCA")
add_subdirectory ("GWCA")
+42
View File
@@ -0,0 +1,42 @@
{
"version": 3,
"configurePresets": [
{
"name": "windows-base",
"hidden": true,
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/${presetName}",
"installDir": "${sourceDir}/install/${presetName}",
"cacheVariables": {
"CMAKE_C_COMPILER": "cl.exe",
"CMAKE_CXX_COMPILER": "cl.exe",
"CMAKE_CXX_FLAGS": "/EHa"
},
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Windows"
}
},
{
"name": "x86-debug",
"displayName": "x86 Debug",
"inherits": "windows-base",
"architecture": {
"value": "x86",
"strategy": "external"
},
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
}
},
{
"name": "x86-release",
"displayName": "x86 Release",
"inherits": "x86-debug",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release"
}
}
]
}
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>Daybreak._7ZipExtractor</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="SharpCompress" Version="0.34.1" />
</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;
+39
View File
@@ -0,0 +1,39 @@
# CMakeList.txt : CMake project for Daybreak.GWCA, include source and define
# project specific logic here.
#
project(Daybreak.GWCA)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
message(FATAL_ERROR "You are configuring a 64bit build, this is not supported. Run cmake with `-A Win32`")
endif()
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(Daybreak.GWCA_FOLDER "${CMAKE_CURRENT_LIST_DIR}/")
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/")
add_library(Daybreak.GWCA SHARED)
file(GLOB SOURCES
"source/pch.h"
"source/*.cpp"
"source/*/*.cpp"
"header/*.h*"
"header/*/*.h")
source_group(TREE "${CMAKE_CURRENT_SOURCE_DIR}" FILES ${SOURCES})
target_sources(Daybreak.GWCA PRIVATE ${SOURCES})
target_compile_features(Daybreak.GWCA PUBLIC cxx_std_17)
target_compile_definitions(Daybreak.GWCA PRIVATE
$<$<CONFIG:Debug>:BUILD_TYPE_DEBUG>
$<$<CONFIG:Release>:BUILD_TYPE_RELEASE>
)
target_precompile_headers(Daybreak.GWCA PRIVATE "header/pch.h")
target_include_directories(Daybreak.GWCA PUBLIC "header")
target_link_libraries(Daybreak.GWCA PUBLIC
gwca
directx
minhook)
+8
View File
@@ -0,0 +1,8 @@
#pragma once
#include "httplib.h"
namespace http {
namespace modules {
void HandleAlive(const httplib::Request&, httplib::Response& res);
}
}
+6
View File
@@ -0,0 +1,6 @@
#pragma once
#include "httplib.h"
namespace Daybreak::Modules::EntityNameModule {
void GetName(const httplib::Request& req, httplib::Response& res);
}
+6
View File
@@ -0,0 +1,6 @@
#pragma once
#include "httplib.h"
namespace Daybreak::Modules::GameModule {
void GetGameInfo(const httplib::Request&, httplib::Response& res);
}
+6
View File
@@ -0,0 +1,6 @@
#pragma once
#include "httplib.h"
namespace Daybreak::Modules::GameStateModule {
void GetGameStateInfo(const httplib::Request&, httplib::Response& res);
}
+6
View File
@@ -0,0 +1,6 @@
#pragma once
#include "httplib.h"
namespace http {
void ConsoleLogger(const httplib::Request req, httplib::Response res);
}
+6
View File
@@ -0,0 +1,6 @@
#pragma once
#include "httplib.h"
namespace Daybreak::Modules::InventoryModule {
void GetInventoryInfo(const httplib::Request&, httplib::Response& res);
}
+6
View File
@@ -0,0 +1,6 @@
#pragma once
#include "httplib.h"
namespace Daybreak::Modules::ItemNameModule {
void GetName(const httplib::Request& req, httplib::Response& res);
}
+6
View File
@@ -0,0 +1,6 @@
#pragma once
#include "httplib.h"
namespace Daybreak::Modules::LoginModule {
void GetLoginInfo(const httplib::Request&, httplib::Response& res);
}
+6
View File
@@ -0,0 +1,6 @@
#pragma once
#include "httplib.h"
namespace Daybreak::Modules::MainPlayerModule {
void GetMainPlayer(const httplib::Request&, httplib::Response& res);
}
+6
View File
@@ -0,0 +1,6 @@
#pragma once
#include "httplib.h"
namespace Daybreak::Modules::MapModule {
void GetMapInfo(const httplib::Request&, httplib::Response& res);
}
@@ -0,0 +1,6 @@
#pragma once
#include "httplib.h"
namespace Daybreak::Modules::PathingMetadataModule {
void GetPathingMetadata(const httplib::Request&, httplib::Response& res);
}
+6
View File
@@ -0,0 +1,6 @@
#pragma once
#include "httplib.h"
namespace Daybreak::Modules::PathingModule {
void GetPathingData(const httplib::Request&, httplib::Response& res);
}
+6
View File
@@ -0,0 +1,6 @@
#pragma once
#include "httplib.h"
namespace Daybreak::Modules::PreGameModule {
void GetPreGameInfo(const httplib::Request&, httplib::Response& res);
}
+8
View File
@@ -0,0 +1,8 @@
#pragma once
#include "httplib.h"
namespace http {
namespace modules {
void HandleProcessId(const httplib::Request&, httplib::Response& res);
}
}
+12
View File
@@ -0,0 +1,12 @@
#pragma once
#include "httplib.h"
#include "pch.h"
namespace http {
namespace server {
bool StartServer();
void StopServer();
void SetLogger(httplib::Logger logger);
void Get(const std::string& pattern, httplib::Server::Handler handler);
}
}
+6
View File
@@ -0,0 +1,6 @@
#pragma once
#include "httplib.h"
namespace Daybreak::Modules::SessionModule {
void GetSessionInfo(const httplib::Request&, httplib::Response& res);
}
+6
View File
@@ -0,0 +1,6 @@
#pragma once
#include "httplib.h"
namespace Daybreak::Modules::UserModule {
void GetUserInfo(const httplib::Request&, httplib::Response& res);
}
+7
View File
@@ -0,0 +1,7 @@
#pragma once
#include <string>
namespace Daybreak::Utils {
std::string WStringToString(const std::wstring& wstr);
bool StringToInt(const std::string& str, int& outValue);
}
+5
View File
@@ -0,0 +1,5 @@
#pragma once
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files
#include <windows.h>
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+18
View File
@@ -0,0 +1,18 @@
#pragma once
#include <cstdint>
#include <GWCA/GameEntities/Map.h>
#include <json.hpp>
using json = nlohmann::json;
namespace Daybreak {
struct Attribute {
uint32_t Id;
uint32_t BaseLevel;
uint32_t ActualLevel;
uint32_t DecrementPoints;
uint32_t IncrementPoints;
};
void to_json(json& j, const Attribute& p);
}
+15
View File
@@ -0,0 +1,15 @@
#pragma once
#include <cstdint>
#include <GWCA/GameEntities/Map.h>
#include <payloads/BagContent.h>
#include <json.hpp>
using json = nlohmann::json;
namespace Daybreak {
struct Bag {
std::list<BagContent> Items;
};
void to_json(json& j, const Bag& p);
}
@@ -0,0 +1,17 @@
#pragma once
#include <cstdint>
#include <GWCA/GameEntities/Map.h>
#include <json.hpp>
using json = nlohmann::json;
namespace Daybreak {
struct BagContent {
uint32_t Id = 0;
uint32_t Slot = 0;
uint32_t Count = 0;
std::list<uint32_t> Modifiers;
};
void to_json(json& j, const BagContent& p);
}
+18
View File
@@ -0,0 +1,18 @@
#pragma once
#include <cstdint>
#include <GWCA/GameEntities/Map.h>
#include <json.hpp>
#include <payloads/Attribute.h>
using json = nlohmann::json;
namespace Daybreak {
struct Build {
uint32_t Primary = 0;
uint32_t Secondary = 0;
std::list<Attribute> Attributes;
std::list<uint32_t> Skills;
};
void to_json(json& j, const Build& p);
}
@@ -0,0 +1,21 @@
#pragma once
#include <cstdint>
#include <GWCA/GameEntities/Map.h>
#include <json.hpp>
#include <payloads/MainPlayer.h>
#include <payloads/MapIcon.h>
using json = nlohmann::json;
namespace Daybreak {
struct GamePayload {
MainPlayer MainPlayer;
std::list<Player> Party;
std::list<WorldPlayer> WorldPlayers;
std::list<LivingEntity> LivingEntities;
std::list<MapIcon> MapIcons;
uint32_t TargetId = 0;
};
void to_json(json& j, const GamePayload& p);
}
@@ -0,0 +1,14 @@
#pragma once
#include <cstdint>
#include <json.hpp>
#include <payloads/StatePayload.h>
using json = nlohmann::json;
namespace Daybreak {
struct GameStatePayload {
std::list<StatePayload> States;
};
void to_json(json& j, const GameStatePayload& p);
}
@@ -0,0 +1,24 @@
#pragma once
#include <cstdint>
#include <GWCA/GameEntities/Map.h>
#include <json.hpp>
#include <payloads/Bag.h>
using json = nlohmann::json;
namespace Daybreak {
struct InventoryPayload {
uint32_t GoldInStorage;
uint32_t GoldOnCharacter;
Bag Backpack;
Bag BeltPouch;
Bag EquipmentPack;
Bag MaterialStorage;
Bag UnclaimedItems;
Bag EquippedItems;
std::list<Bag> Bags;
std::list<Bag> StoragePanes;
};
void to_json(json& j, const InventoryPayload& p);
}
@@ -0,0 +1,25 @@
#pragma once
#include <cstdint>
#include <GWCA/GameEntities/Map.h>
#include <json.hpp>
using json = nlohmann::json;
namespace Daybreak {
struct LivingEntity {
uint32_t Id = 0;
uint32_t Timer = 0;
float PosX = 0;
float PosY = 0;
uint32_t NpcDefinition = 0;
uint32_t PrimaryProfessionId = 0;
uint32_t SecondaryProfessionId = 0;
uint32_t Level = 0;
uint32_t EntityState = 0;
uint32_t EntityAllegiance = 0;
float Health;
float Energy;
};
void to_json(json& j, const LivingEntity& p);
}
@@ -0,0 +1,15 @@
#pragma once
#include <cstdint>
#include <GWCA/GameEntities/Map.h>
#include <json.hpp>
using json = nlohmann::json;
namespace Daybreak {
struct LoginPayload {
std::string Email;
std::string PlayerName;
};
void to_json(json& j, const LoginPayload& p);
}
@@ -0,0 +1,24 @@
#pragma once
#include <cstdint>
#include <GWCA/GameEntities/Map.h>
#include <json.hpp>
#include <payloads/WorldPlayer.h>
#include <payloads/QuestMetadata.h>
using json = nlohmann::json;
namespace Daybreak {
struct MainPlayer : public WorldPlayer {
uint32_t CurrentQuest = 0;
std::list<QuestMetadata> QuestLog;
bool HardModeUnlocked = false;
uint32_t Experience = 0;
uint32_t Morale = 0;
float CurrentHp = 0;
uint32_t MaxHp = 0;
float CurrentEnergy = 0;
uint32_t MaxEnergy = 0;
};
void to_json(json& j, const MainPlayer& p);
}
+17
View File
@@ -0,0 +1,17 @@
#pragma once
#include <cstdint>
#include <GWCA/GameEntities/Map.h>
#include <json.hpp>
using json = nlohmann::json;
namespace Daybreak {
struct MapIcon {
uint32_t Id;
float PosX;
float PosY;
uint32_t Affiliation;
};
void to_json(json& j, const MapIcon& p);
}
@@ -0,0 +1,21 @@
#pragma once
#include <cstdint>
#include <GWCA/GameEntities/Map.h>
#include <json.hpp>
using json = nlohmann::json;
namespace Daybreak {
struct MapPayload {
bool IsLoaded;
uint32_t Id;
uint32_t InstanceType;
uint32_t Timer;
uint32_t Campaign;
uint32_t Continent;
uint32_t Region;
uint32_t Type;
};
void to_json(json& j, const MapPayload& p);
}
@@ -0,0 +1,14 @@
#pragma once
#include <cstdint>
#include <json.hpp>
using json = nlohmann::json;
namespace Daybreak {
struct NamePayload {
uint32_t Id = 0;
std::string Name = "";
};
void to_json(json& j, const NamePayload& p);
}
@@ -0,0 +1,14 @@
#pragma once
#include <cstdint>
#include <GWCA/GameEntities/Map.h>
#include <json.hpp>
using json = nlohmann::json;
namespace Daybreak {
struct PathingMetadataPayload {
uint32_t TrapezoidCount;
};
void to_json(json& j, const PathingMetadataPayload& p);
}
@@ -0,0 +1,16 @@
#pragma once
#include <cstdint>
#include <GWCA/GameEntities/Map.h>
#include <payloads/PathingTrapezoid.h>
#include <json.hpp>
using json = nlohmann::json;
namespace Daybreak {
struct PathingPayload {
std::list<PathingTrapezoid> Trapezoids;
std::list<std::list<int>> AdjacencyList;
};
void to_json(json& j, const PathingPayload& p);
}
@@ -0,0 +1,21 @@
#pragma once
#include <cstdint>
#include <GWCA/GameEntities/Map.h>
#include <json.hpp>
using json = nlohmann::json;
namespace Daybreak {
struct PathingTrapezoid {
uint32_t Id;
uint32_t PathingMapId;
float XTL;
float XTR;
float XBL;
float XBR;
float YT;
float YB;
};
void to_json(json& j, const PathingTrapezoid& p);
}
+18
View File
@@ -0,0 +1,18 @@
#pragma once
#include <cstdint>
#include <GWCA/GameEntities/Map.h>
#include <json.hpp>
#include <payloads/LivingEntity.h>
#include <payloads/Build.h>
using json = nlohmann::json;
namespace Daybreak {
struct Player : public LivingEntity {
std::list<uint32_t> UnlockedProfession;
uint32_t NpcDefinition = 0;
Build Build;
};
void to_json(json& j, const Player& p);
}
@@ -0,0 +1,14 @@
#pragma once
#include <cstdint>
#include <json.hpp>
using json = nlohmann::json;
namespace Daybreak {
struct PreGamePayload {
int ChosenCharacterIndex;
std::list<std::string> Characters;
};
void to_json(json& j, const PreGamePayload& p);
}
@@ -0,0 +1,18 @@
#pragma once
#include <cstdint>
#include <GWCA/GameEntities/Map.h>
#include <json.hpp>
using json = nlohmann::json;
namespace Daybreak {
struct QuestMetadata {
uint32_t Id;
float PosX;
float PosY;
uint32_t FromId;
uint32_t ToId;
};
void to_json(json& j, const QuestMetadata& p);
}
@@ -0,0 +1,17 @@
#pragma once
#include <cstdint>
#include <json.hpp>
using json = nlohmann::json;
namespace Daybreak {
struct SessionPayload {
uint32_t FoesKilled = 0;
uint32_t FoesToKill = 0;
uint32_t MapId = 0;
uint32_t InstanceTimer = 0;
uint32_t InstanceType = 0;
};
void to_json(json& j, const SessionPayload& p);
}
@@ -0,0 +1,18 @@
#pragma once
#include <cstdint>
#include <json.hpp>
using json = nlohmann::json;
namespace Daybreak {
struct StatePayload {
uint32_t Id = 0;
float PosX = 0;
float PosY = 0;
uint32_t State = 0;
float Health = 0;
float Energy = 0;
};
void to_json(json& j, const StatePayload& p);
}
+20
View File
@@ -0,0 +1,20 @@
#pragma once
#include <cstdint>
#include <GWCA/GameEntities/Map.h>
#include <json.hpp>
using json = nlohmann::json;
namespace Daybreak {
struct Title {
uint32_t Id = 0;
uint32_t CurrentPoints = 0;
uint32_t PointsForCurrentRank = 0;
uint32_t PointsForNextRank = 0;
uint32_t TierNumber = 0;
uint32_t MaxTierNumber = 0;
bool IsPercentage = false;
};
void to_json(json& j, const Title& p);
}
@@ -0,0 +1,27 @@
#pragma once
#include <cstdint>
#include <json.hpp>
using json = nlohmann::json;
namespace Daybreak {
struct UserPayload {
std::string Email;
uint32_t CurrentKurzickPoints;
uint32_t TotalKurzickPoints;
uint32_t CurrentLuxonPoints;
uint32_t TotalLuxonPoints;
uint32_t CurrentImperialPoints;
uint32_t TotalImperialPoints;
uint32_t CurrentBalthazarPoints;
uint32_t TotalBalthazarPoints;
uint32_t CurrentSkillPoints;
uint32_t TotalSkillPoints;
uint32_t MaxKurzickPoints;
uint32_t MaxLuxonPoints;
uint32_t MaxImperialPoints;
uint32_t MaxBalthazarPoints;
};
void to_json(json& j, const UserPayload& p);
}
@@ -0,0 +1,17 @@
#pragma once
#include <cstdint>
#include <GWCA/GameEntities/Map.h>
#include <json.hpp>
#include <payloads/Player.h>
#include <payloads/Title.h>
using json = nlohmann::json;
namespace Daybreak {
struct WorldPlayer : public Player {
std::string Name = "";
Title Title;
};
void to_json(json& j, const WorldPlayer& p);
}
+13
View File
@@ -0,0 +1,13 @@
// pch.h: This is a precompiled header file.
// Files listed below are compiled only once, improving build performance for future builds.
// This also affects IntelliSense performance, including code completion and many code browsing features.
// However, files listed here are ALL re-compiled if any one of them is updated between builds.
// Do not add files here that you will be updating frequently as this negates the performance advantage.
#ifndef PCH_H
#define PCH_H
// add headers that you want to pre-compile here
#include "framework.h"
#endif //PCH_H
+5
View File
@@ -0,0 +1,5 @@
#pragma once
namespace PipeServer {
void StartServer();
}
+73
View File
@@ -0,0 +1,73 @@
#pragma once
#pragma warning(disable: 4619) // there is no warning number 'number'
#pragma warning(push)
#pragma warning(disable: 4061) // enumerator 'identifier' in switch of enum 'enumeration' is not explicitly handled by a case label
#pragma warning(disable: 4365) // 'action' : conversion from 'type_1' to 'type_2', signed/unsigned mismatch
#pragma warning(disable: 4514) // 'function' : unreferenced inline function has been removed
#pragma warning(disable: 4530) // C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc
#pragma warning(disable: 4577) // 'noexcept' used with no exception handling mode specified; termination on exception is not guaranteed. Specify /EHsc
#pragma warning(disable: 4623) // 'derived class' : default constructor was implicitly defined as deleted because a base class default constructor is inaccessible or deleted
#pragma warning(disable: 4625) // 'derived class' : copy constructor was implicitly defined as deleted because a base class copy constructor is inaccessible or deleted
#pragma warning(disable: 4626) // 'derived class' : assignment operator was implicitly defined as deleted because a base class assignment operator is inaccessible or deleted
#pragma warning(disable: 4668) // 'symbol' is not defined as a preprocessor macro, replacing with '0' for 'directives'
#pragma warning(disable: 4710) // 'function' : function not inlined
#pragma warning(disable: 4711) // function 'function' selected for inline expansion
#pragma warning(disable: 4820) // 'bytes' bytes padding added after construct 'member_name'
#pragma warning(disable: 4917) // 'declarator' : a GUID can only be associated with a class, interface or namespace
#pragma warning(disable: 5026) // 'type': move constructor was implicitly defined as deleted
#pragma warning(disable: 5027) // 'type': move assignment operator was implicitly defined as deleted
#pragma warning(disable: 5039) // 'function': pointer or reference to potentially throwing function passed to extern C function under -EHc. Undefined behavior may occur if this function throws an exception.
#pragma warning(disable: 5045) // Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified
#ifndef _CRT_SECURE_NO_WARNINGS
# define _CRT_SECURE_NO_WARNINGS 1
#endif
#include <cmath>
#include <cstdio>
#include <cstdint>
#include <cstring>
#include <map>
#include <atomic>
#include <string>
#include <vector>
#include <sstream>
#include <algorithm>
#include <functional>
#include <unordered_map>
#include <utility>
#ifndef NOMINMAX
# define NOMINMAX
#endif
#ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
#endif
#include <Windows.h>
#include <ShellApi.h>
#pragma warning(pop)
#pragma warning(disable: 4061) // enumerator 'identifier' in switch of enum 'enumeration' is not explicitly handled by a case label
#pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union
#pragma warning(disable: 4514) // 'function' : unreferenced inline function has been removed
#pragma warning(disable: 4505) // 'function' : unreferenced local function has been removed
#pragma warning(disable: 4530) // C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc
#pragma warning(disable: 4577) // 'noexcept' used with no exception handling mode specified; termination on exception is not guaranteed. Specify /EHsc
#pragma warning(disable: 4623) // 'derived class' : default constructor was implicitly defined as deleted because a base class default constructor is inaccessible or deleted
#pragma warning(disable: 4625) // 'derived class' : copy constructor was implicitly defined as deleted because a base class copy constructor is inaccessible or deleted
#pragma warning(disable: 4626) // 'derived class' : assignment operator was implicitly defined as deleted because a base class assignment operator is inaccessible or deleted
#pragma warning(disable: 4710) // 'function' : function not inlined
#pragma warning(disable: 4711) // function 'function' selected for inline expansion
#pragma warning(disable: 4774) // 'swprintf' : format string expected in argument 3 is not a string literal
#pragma warning(disable: 4820) // 'bytes' bytes padding added after construct 'member_name'
#pragma warning(disable: 5026) // 'type': move constructor was implicitly defined as deleted
#pragma warning(disable: 5027) // 'type': move assignment operator was implicitly defined as deleted
#pragma warning(disable: 5045) // Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified
#pragma warning(disable: 28159) // Consider using 'GetTickCount64' instead of 'GetTickCount'.
+36
View File
@@ -0,0 +1,36 @@
#pragma once
#include <cstdint>
#include <GWCA/GameEntities/Map.h>
#include <json.hpp>
#include <payloads/LivingEntity.h>
#include <payloads/Build.h>
#include <GWCA/GameContainers/Array.h>
using json = nlohmann::json;
namespace Daybreak::Temp {
struct GWPlayer { // total: 0x4C/76
/* +h0000 */ uint32_t agent_id;
/* +h0004 */ uint32_t h0004[3];
/* +h0010 */ uint32_t appearance_bitmap;
/* +h0014 */ uint32_t flags; // Bitwise field
/* +h0018 */ uint32_t primary;
/* +h001C */ uint32_t secondary;
/* +h0020 */ uint32_t h0020;
/* +h0024 */ wchar_t* name_enc;
/* +h0028 */ wchar_t* name;
/* +h002C */ uint32_t party_leader_player_number;
/* +h0030 */ uint32_t active_title_tier;
/* +h0034 */ uint32_t player_number;
/* +h0038 */ uint32_t party_size;
/* +h003C */ uint32_t m_buffer; // +h0000
/* +h0040 */ uint32_t m_capacity; // +h0004
/* +h0044 */ uint32_t m_size; // +h0008
/* +h0048 */ uint32_t m_param;
inline bool IsPvP() {
return (flags & 0x800) != 0;
}
};
}
+10
View File
@@ -0,0 +1,10 @@
#include "pch.h"
#include "AliveModule.h"
namespace http {
namespace modules {
void HandleAlive(const httplib::Request&, httplib::Response& res) {
res.set_content("Yes!", "text/plain");
}
}
}
+129
View File
@@ -0,0 +1,129 @@
#include "pch.h"
#include "EntityNameModule.h"
#include "payloads/NamePayload.h"
#include <GWCA/Managers/GameThreadMgr.h>
#include <GWCA/Managers/MapMgr.h>
#include <GWCA/GameEntities/Agent.h>
#include <future>
#include <json.hpp>
#include <tuple>
#include <queue>
#include <GWCA/GWCA.h>
#include <GWCA/Context/PreGameContext.h>
#include <GWCA/Managers/AgentMgr.h>
#include <Windows.h>
#include <cstdint>
#include <limits>
#include "Utils.h"
namespace Daybreak::Modules::EntityNameModule {
std::vector<std::tuple<uint32_t, std::promise<NamePayload>*, std::wstring*>> WaitingList;
std::queue<std::tuple<uint32_t, std::promise<NamePayload>>*> PromiseQueue;
std::mutex GameThreadMutex;
GW::HookEntry GameThreadHook;
volatile bool initialized = false;
std::wstring* GetAsyncName(uint32_t id) {
NamePayload namePayload;
auto agent = GW::Agents::GetAgentByID(id);
if (!agent) {
return nullptr;
}
auto agentLiving = agent->GetAsAgentLiving();
if (!agentLiving) {
return nullptr;
}
auto name = new std::wstring();
if (!GW::Agents::AsyncGetAgentName(agentLiving, *name)) {
delete(name);
return nullptr;
}
return name;
}
void EnsureInitialized() {
GameThreadMutex.lock();
if (!initialized) {
GW::GameThread::RegisterGameThreadCallback(&GameThreadHook, [&](GW::HookStatus*) {
while (!PromiseQueue.empty()) {
auto promiseRequest = PromiseQueue.front();
std::promise<NamePayload> &promise = std::get<1>(*promiseRequest);
uint32_t id = std::get<0>(*promiseRequest);
PromiseQueue.pop();
try {
auto name = GetAsyncName(id);
if (!name) {
continue;
}
WaitingList.emplace_back(id, &promise, name);
}
catch (...) {
NamePayload payload;
promise.set_value(payload);
}
}
for (auto i = 0; i < WaitingList.size(); ) {
auto item = &WaitingList[i];
auto name = std::get<2>(*item);
if (name->empty()) {
i++;
continue;
}
auto promise = std::get<1>(*item);
auto id = std::get<0>(*item);
WaitingList.erase(WaitingList.begin() + i);
NamePayload payload;
payload.Id = id;
payload.Name = Daybreak::Utils::WStringToString(*name);
delete(name);
promise->set_value(payload);
}
});
initialized = true;
}
GameThreadMutex.unlock();
}
void GetName(const httplib::Request& req, httplib::Response& res) {
auto callbackEntry = new GW::HookEntry;
uint32_t id = 0;
auto it = req.params.find("id");
if (it == req.params.end()) {
res.status = 400;
res.set_content("Missing id parameter", "text/plain");
return;
}
else {
auto idStr = it->second;
size_t pos = 0;
auto result = std::stoul(idStr, &pos);
if (pos != idStr.size()) {
res.status = 400;
res.set_content("Invalid id parameter", "text/plain");
return;
}
id = static_cast<uint32_t>(result);
}
auto response = new std::tuple<uint32_t, std::promise<NamePayload>>();
std::get<0>(*response) = id;
std::promise<NamePayload>& promise = std::get<1>(*response);
EnsureInitialized();
PromiseQueue.emplace(response);
json responsePayload = promise.get_future().get();
delete callbackEntry;
delete response;
res.set_content(responsePayload.dump(), "text/json");
}
}
+608
View File
@@ -0,0 +1,608 @@
#include "pch.h"
#include "GameModule.h"
#include <GWCA/Managers/GameThreadMgr.h>
#include <GWCA/Managers/MapMgr.h>
#include <GWCA/Managers/AgentMgr.h>
#include <GWCA/Managers/PartyMgr.h>
#include <GWCA/Managers/PlayerMgr.h>
#include <GWCA/Managers/SkillbarMgr.h>
#include <GWCA/Managers/QuestMgr.h>
#include <GWCA/Context/WorldContext.h>
#include <GWCA/GameContainers/Array.h>
#include <GWCA/GameEntities/Skill.h>
#include <GWCA/GameEntities/Quest.h>
#include <GWCA/GameEntities/Agent.h>
#include <GWCA/GameEntities/Title.h>
#include <GWCA/GameEntities/Party.h>
#include <GWCA/GameEntities/Attribute.h>
#include <GWCA/GameEntities/Player.h>
#include <GWCA/GameEntities/NPC.h>
#include <GWCA/Constants/Constants.h>
#include <temp/GWPlayer.h>
#include <future>
#include <payloads/GamePayload.h>
#include <json.hpp>
#include <queue>
#include <algorithm>
#include "Utils.h"
namespace Daybreak::Modules::GameModule {
std::queue<std::promise<GamePayload>*> PromiseQueue;
std::mutex GameThreadMutex;
GW::HookEntry GameThreadHook;
volatile bool initialized = false;
std::list<QuestMetadata> GetQuestLog() {
std::list<QuestMetadata> questMetadatas;
auto questLog = GW::QuestMgr::GetQuestLog();
if (!questLog) {
return questMetadatas;
}
for (auto& quest : *questLog) {
QuestMetadata metadata;
metadata.FromId = (uint32_t)quest.map_from;
metadata.ToId = (uint32_t)quest.map_to;
metadata.Id = (uint32_t)quest.quest_id;
metadata.PosX = quest.marker.x;
metadata.PosY = quest.marker.y;
questMetadatas.push_back(metadata);
}
return questMetadatas;
}
std::vector<GW::MapAgent> GetMapEntities() {
std::vector<GW::MapAgent> entities;
auto worldContext = GW::GetWorldContext();
for (auto& agent : worldContext->map_agents) {
entities.push_back(agent);
}
return entities;
}
std::list<GW::PartyAttribute> GetPartyAttributes() {
std::list<GW::PartyAttribute> attributes;
auto worldContext = GW::GetWorldContext();
for (auto& attribute : worldContext->attributes) {
attributes.push_back(attribute);
}
return attributes;
}
std::list<GW::ProfessionState> GetProfessions() {
std::list<GW::ProfessionState> professions;
auto worldContext = GW::GetWorldContext();
for (auto& profession : worldContext->party_profession_states) {
professions.push_back(profession);
}
return professions;
}
std::list<GW::AgentLiving> GetLivingAgents() {
std::list<GW::AgentLiving> agentList;
const GW::AgentArray* agents_ptr = GW::Agents::GetAgentArray();
GW::AgentArray* agents = GW::Agents::GetAgentArray();
if (!agents) {
return agentList;
}
for (auto* a : *agents) {
const GW::AgentLiving* agent = a ? a->GetAsAgentLiving() : nullptr;
if (agent) {
agentList.push_back(*agent);
}
}
return agentList;
}
std::vector<GW::TitleTier> GetTitleTiers() {
std::vector<GW::TitleTier> titles;
auto worldContext = GW::GetWorldContext();
for (auto& title : worldContext->title_tiers) {
titles.push_back(title);
}
return titles;
}
std::list<GW::Title> GetTitles() {
std::list<GW::Title> titles;
auto worldContext = GW::GetWorldContext();
for (auto& title : worldContext->titles) {
titles.push_back(title);
}
return titles;
}
std::list<Temp::GWPlayer> GetPlayers() {
std::list<Temp::GWPlayer> players;
auto worldContext = GW::GetWorldContext();
Temp::GWPlayer *tempPlayerArray = (Temp::GWPlayer*)worldContext->players.m_buffer;
if (!tempPlayerArray) {
return players;
}
for (auto i = 0; i < worldContext->players.m_size; i++) {
if (tempPlayerArray->agent_id != 0) {
players.push_back(*tempPlayerArray);
}
tempPlayerArray++;
}
return players;
}
std::map<uint32_t, std::list<uint32_t>> GetSkillbars() {
std::map<uint32_t, std::list<uint32_t>> skillbarMap;
auto skillbars = GW::SkillbarMgr::GetSkillbarArray();
if (!skillbars) {
return skillbarMap;
}
for (auto& skillbar : *skillbars) {
std::list<uint32_t> skillList;
skillList.push_back((uint32_t)skillbar.skills[0].skill_id);
skillList.push_back((uint32_t)skillbar.skills[1].skill_id);
skillList.push_back((uint32_t)skillbar.skills[2].skill_id);
skillList.push_back((uint32_t)skillbar.skills[3].skill_id);
skillList.push_back((uint32_t)skillbar.skills[4].skill_id);
skillList.push_back((uint32_t)skillbar.skills[5].skill_id);
skillList.push_back((uint32_t)skillbar.skills[6].skill_id);
skillList.push_back((uint32_t)skillbar.skills[7].skill_id);
skillbarMap[skillbar.agent_id] = skillList;
}
return skillbarMap;
}
std::list<LivingEntity> GetLivingEntities(
std::list<GW::AgentLiving> agents) {
std::list<LivingEntity> entities;
for (auto& agent : agents) {
LivingEntity entity;
entity.PrimaryProfessionId = agent.primary;
entity.SecondaryProfessionId = agent.secondary;
entity.EntityState = agent.type_map;
entity.EntityAllegiance = (uint32_t)agent.allegiance;
entity.NpcDefinition = agent.player_number;
entity.Id = agent.agent_id;
entity.Timer = agent.timer;
entity.Level = agent.level;
entity.PosX = agent.pos.x;
entity.PosY = agent.pos.y;
entity.Health = agent.hp;
entity.Energy = agent.energy;
if (agent.primary == 0) {
const auto npc = GW::Agents::GetNPCByID(agent.player_number);
if (npc) {
entity.PrimaryProfessionId = npc->primary;
}
}
entities.push_back(entity);
}
return entities;
}
void PopulatePlayer(
Player& player,
int playerId,
GW::ProfessionState* professionState,
std::list<uint32_t> skillbar,
GW::PartyAttribute* partyAttribute,
GW::AgentLiving* agent) {
std::list<uint32_t> unlockedProfessions;
if (professionState) {
for (auto i = 0; i < 11; i++) {
auto prof = (GW::Constants::Profession)i;
if (professionState->IsProfessionUnlocked(prof)) {
unlockedProfessions.push_back(i);
}
}
unlockedProfessions.push_back((uint32_t)professionState->primary);
}
Build build;
std::list<Attribute> attributes;
if (partyAttribute) {
for (const auto& partyAttr : partyAttribute->attribute) {
if (((uint32_t)partyAttr.id < 0) ||
((uint32_t)partyAttr.id > 44) ||
partyAttr.level <= 0) {
continue;
}
Attribute attribute;
attribute.Id = (uint32_t)partyAttr.id;
attribute.BaseLevel = partyAttr.level_base;
attribute.ActualLevel = partyAttr.level;
attribute.DecrementPoints = partyAttr.decrement_points;
attribute.IncrementPoints = partyAttr.increment_points;
attributes.push_back(attribute);
}
build.Attributes = attributes;
if (agent) {
build.Primary = (uint32_t)agent->primary;
build.Secondary = (uint32_t)agent->secondary;
}
else if (professionState) {
build.Primary = (uint32_t)professionState->primary;
build.Secondary = (uint32_t)professionState->secondary;
}
build.Skills = skillbar;
player.Build = build;
}
player.UnlockedProfession = unlockedProfessions;
player.Id = playerId;
if (agent) {
player.PosX = agent->pos.x;
player.PosY = agent->pos.y;
player.Timer = agent->timer;
player.Level = agent->level;
player.NpcDefinition = agent->player_number;
player.PrimaryProfessionId = (uint32_t)agent->primary;
player.SecondaryProfessionId = (uint32_t)agent->secondary;
player.Health = agent->hp * (agent->max_hp > 0 ? agent->max_hp : 1);
player.Energy = agent->energy * (agent->max_energy > 0 ? agent->max_energy : 1);
}
else if (professionState) {
player.PrimaryProfessionId = (uint32_t)professionState->primary;
player.SecondaryProfessionId = (uint32_t)professionState->secondary;
}
}
void PopulateWorldPlayer(
std::list<GW::Title> titles,
std::vector<GW::TitleTier> titleTiers,
WorldPlayer& player,
int playerId,
Temp::GWPlayer* gwPlayer,
GW::ProfessionState* professionState,
std::list<uint32_t> skillbar,
GW::PartyAttribute* partyAttribute,
GW::AgentLiving* agent) {
PopulatePlayer(player, playerId, professionState, skillbar, partyAttribute, agent);
if (!gwPlayer) {
return;
}
GW::Title gwTitle;
Title title;
int titleId = 0;
std::wstring nameString(gwPlayer->name);
auto name = Daybreak::Utils::WStringToString(nameString);
player.Name = name;
for (const auto &t : titles) {
if (t.current_title_tier_index == gwPlayer->active_title_tier) {
gwTitle = t;
break;
}
titleId++;
}
if (gwTitle.current_title_tier_index >= titleTiers.size()) {
return;
}
auto titleTier = titleTiers[gwTitle.current_title_tier_index];
title.CurrentPoints = gwTitle.current_points;
title.IsPercentage = gwTitle.is_percentage_based();
title.PointsForCurrentRank = gwTitle.points_needed_current_rank;
title.PointsForNextRank = titleTier.tier_number == gwTitle.max_title_rank ? gwTitle.current_points : gwTitle.points_needed_next_rank;
title.TierNumber = titleTier.tier_number;
title.MaxTierNumber = gwTitle.max_title_rank;
title.Id = titleId;
player.Title = title;
}
void PopulateMainPlayer(
MainPlayer& player,
int activeQuestId,
std::list<QuestMetadata> questLog,
std::list<GW::Title> titles,
std::vector<GW::TitleTier> titleTiers,
int playerId,
Temp::GWPlayer* gwPlayer,
GW::ProfessionState* professionState,
std::list<uint32_t> skillbar,
GW::PartyAttribute* partyAttribute,
GW::AgentLiving* agent) {
PopulateWorldPlayer(titles, titleTiers, player, playerId, gwPlayer, professionState, skillbar, partyAttribute, agent);
player.CurrentQuest = activeQuestId;
player.QuestLog = questLog;
player.HardModeUnlocked = GW::GetWorldContext()->is_hard_mode_unlocked == 1;
player.Experience = GW::GetWorldContext()->experience;
player.Morale = GW::GetWorldContext()->morale;
if (agent) {
player.CurrentEnergy = agent->max_energy * agent->energy;
player.CurrentHp = agent->max_hp * agent->hp;
player.MaxEnergy = agent->max_energy;
player.MaxHp = agent->max_hp;
}
}
GamePayload GetPayload() {
GamePayload gamePayload;
gamePayload.TargetId = 0;
if (!GW::Map::GetIsMapLoaded()) {
return gamePayload;
}
gamePayload.TargetId = GW::Agents::GetTargetId();
auto worldContext = GW::GetWorldContext();
auto activeQuestId = GW::QuestMgr::GetActiveQuestId();
auto questLog = GetQuestLog();
auto skillbars = GetSkillbars();
if (skillbars.empty()) {
return gamePayload;
}
auto agents = GetLivingAgents();
if (agents.empty()) {
return gamePayload;
}
auto titles = GetTitles();
if (titles.empty()) {
return gamePayload;
}
auto titleTiers = GetTitleTiers();
if (titleTiers.empty()) {
return gamePayload;
}
auto players = GetPlayers();
if (players.empty()) {
return gamePayload;
}
auto attributes = GetPartyAttributes();
if (attributes.empty()) {
return gamePayload;
}
auto professions = GetProfessions();
if (professions.empty()) {
return gamePayload;
}
auto mapAgents = GetMapEntities();
if (mapAgents.empty()) {
return gamePayload;
}
auto playerAgentId = GW::Agents::GetPlayerId();
std::list<MapIcon> mapIcons;
for (const auto &icon : worldContext->mission_map_icons) {
MapIcon mapIcon;
mapIcon.Id = icon.model_id;
mapIcon.Affiliation = icon.option;
mapIcon.PosX = icon.X;
mapIcon.PosY = icon.Y;
mapIcons.push_back(mapIcon);
}
gamePayload.MapIcons = mapIcons;
std::list<Player> partyMembers;
for (auto &prof : professions) {
if (prof.agent_id == playerAgentId) {
continue;
}
Player player;
auto foundAttr = std::find_if(attributes.begin(), attributes.end(), [&](GW::PartyAttribute attribute) {
return prof.agent_id == attribute.agent_id;
});
auto foundAgent = std::find_if(agents.begin(), agents.end(), [&](GW::AgentLiving agentLiving) {
return prof.agent_id == agentLiving.agent_id;
});
GW::AgentLiving* agentPtr;
if (foundAgent == agents.end()) {
agentPtr = nullptr;
}
else {
agentPtr = &*foundAgent;
}
GW::PartyAttribute* attrPtr;
if (foundAttr == attributes.end()) {
attrPtr = nullptr;
}
else {
attrPtr = &*foundAttr;
}
PopulatePlayer(player, prof.agent_id, &prof, skillbars[prof.agent_id], attrPtr, agentPtr);
partyMembers.push_back(player);
}
gamePayload.Party = partyMembers;
MainPlayer mainPlayer;
auto foundMainAttr = std::find_if(attributes.begin(), attributes.end(), [&](GW::PartyAttribute attribute) {
return playerAgentId == attribute.agent_id;
});
auto foundMainAgent = std::find_if(agents.begin(), agents.end(), [&](GW::AgentLiving agentLiving) {
return playerAgentId == agentLiving.agent_id;
});
auto foundMainProfessionsState = std::find_if(professions.begin(), professions.end(), [&](GW::ProfessionState professionState) {
return playerAgentId == professionState.agent_id;
});
auto foundMainGwPlayer = std::find_if(players.begin(), players.end(), [&](Temp::GWPlayer gwPlayer) {
return playerAgentId == gwPlayer.agent_id;
});
GW::AgentLiving* mainAgentPtr;
if (foundMainAgent == agents.end()) {
mainAgentPtr = nullptr;
}
else {
mainAgentPtr = &*foundMainAgent;
}
GW::PartyAttribute* mainAttrPtr;
if (foundMainAttr == attributes.end()) {
mainAttrPtr = nullptr;
}
else {
mainAttrPtr = &*foundMainAttr;
}
GW::ProfessionState* mainProfPtr;
if (foundMainProfessionsState == professions.end()) {
mainProfPtr = nullptr;
}
else {
mainProfPtr = &*foundMainProfessionsState;
}
Temp::GWPlayer* mainGwPlayer;
if (foundMainGwPlayer == players.end()) {
mainGwPlayer = nullptr;
}
else{
mainGwPlayer = &*foundMainGwPlayer;
}
PopulateMainPlayer(mainPlayer, (uint32_t)activeQuestId, questLog, titles, titleTiers, playerAgentId, mainGwPlayer, mainProfPtr, skillbars[playerAgentId], mainAttrPtr, mainAgentPtr);
gamePayload.MainPlayer = mainPlayer;
std::list<WorldPlayer> worldPlayers;
for (auto& gwPlayer : players) {
if (gwPlayer.agent_id == 0 ||
gwPlayer.agent_id == playerAgentId) {
continue;
}
WorldPlayer worldPlayer;
auto foundWorldProfessionsState = std::find_if(professions.begin(), professions.end(), [&](GW::ProfessionState professionState) {
return gwPlayer.agent_id == professionState.agent_id;
});
auto foundWorldAttr = std::find_if(attributes.begin(), attributes.end(), [&](GW::PartyAttribute attribute) {
return gwPlayer.agent_id == attribute.agent_id;
});
auto foundWorldAgent = std::find_if(agents.begin(), agents.end(), [&](GW::AgentLiving agentLiving) {
return gwPlayer.agent_id == agentLiving.agent_id;
});
std::list<uint32_t> skills;
auto foundSkillbar = skillbars.find(gwPlayer.agent_id);
if (foundSkillbar != skillbars.end()){
skills = foundSkillbar->second;
}
GW::AgentLiving* worldAgentPtr;
if (foundWorldAgent == agents.end()) {
worldAgentPtr = nullptr;
}
else {
worldAgentPtr = &*foundWorldAgent;
}
GW::PartyAttribute* worldAttrPtr;
if (foundWorldAttr == attributes.end()) {
worldAttrPtr = nullptr;
}
else {
worldAttrPtr = &*foundWorldAttr;
}
GW::ProfessionState* worldProfPtr;
if (foundWorldProfessionsState == professions.end()) {
worldProfPtr = nullptr;
}
else {
worldProfPtr = &*foundWorldProfessionsState;
}
auto* tempGwPlayer = &gwPlayer;
PopulateWorldPlayer(titles, titleTiers, worldPlayer, gwPlayer.agent_id, tempGwPlayer, worldProfPtr, skills, worldAttrPtr, worldAgentPtr);
worldPlayers.push_back(worldPlayer);
}
gamePayload.WorldPlayers = worldPlayers;
std::list<GW::AgentLiving> livingEntities;
for (const auto& agentLiving : agents) {
/*
* Get all living entities that are not the main player, a world player or a party member.
*/
if (!agentLiving.GetIsLivingType() ||
agentLiving.agent_id == playerAgentId) {
continue;
}
auto foundPartyMember = std::find_if(partyMembers.begin(), partyMembers.end(), [&](Daybreak::Player player) { return player.Id == agentLiving.agent_id; });
if (foundPartyMember != partyMembers.end()) {
continue;
}
auto foundWorldPlayer = std::find_if(worldPlayers.begin(), worldPlayers.end(), [&](Daybreak::WorldPlayer player) { return player.Id == agentLiving.agent_id; });
if (foundWorldPlayer != worldPlayers.end()) {
continue;
}
livingEntities.push_back(agentLiving);
}
auto livingEntityList = GetLivingEntities(livingEntities);
gamePayload.LivingEntities = livingEntityList;
return gamePayload;
}
void EnsureInitialized() {
GameThreadMutex.lock();
if (!initialized) {
GW::GameThread::RegisterGameThreadCallback(&GameThreadHook, [&](GW::HookStatus*) {
while (!PromiseQueue.empty()) {
auto promise = PromiseQueue.front();
PromiseQueue.pop();
try {
auto payload = GetPayload();
promise->set_value(payload);
}
catch (...) {
GamePayload payload;
promise->set_value(payload);
}
}
});
initialized = true;
}
GameThreadMutex.unlock();
}
void GetGameInfo(const httplib::Request&, httplib::Response& res) {
auto callbackEntry = new GW::HookEntry;
auto response = new std::promise<GamePayload>;
EnsureInitialized();
PromiseQueue.emplace(response);
json responsePayload = response->get_future().get();
delete callbackEntry;
delete response;
res.set_content(responsePayload.dump(), "text/json");
}
}
+106
View File
@@ -0,0 +1,106 @@
#include "pch.h"
#include "GameStateModule.h"
#include <GWCA/Managers/GameThreadMgr.h>
#include <GWCA/Managers/AgentMgr.h>
#include <GWCA/GameEntities/Agent.h>
#include <GWCA/Managers/MapMgr.h>
#include <future>
#include <payloads/GameStatePayload.h>
#include <json.hpp>
#include <queue>
#include <algorithm>
namespace Daybreak::Modules::GameStateModule {
std::queue<std::promise<GameStatePayload>*> PromiseQueue;
std::mutex GameThreadMutex;
GW::HookEntry GameThreadHook;
volatile bool initialized = false;
std::list<GW::AgentLiving> GetLivingAgents() {
std::list<GW::AgentLiving> agentList;
const GW::AgentArray* agents_ptr = GW::Agents::GetAgentArray();
GW::AgentArray* agents = GW::Agents::GetAgentArray();
if (!agents) {
return agentList;
}
for (auto* a : *agents) {
const GW::AgentLiving* agent = a ? a->GetAsAgentLiving() : nullptr;
if (agent) {
agentList.push_back(*agent);
}
}
return agentList;
}
std::list<StatePayload> GetStates(
std::list<GW::AgentLiving> agents) {
std::list<StatePayload> states;
for (auto& agent : agents) {
StatePayload state;
state.Id = agent.agent_id;
state.PosX = agent.pos.x;
state.PosY = agent.pos.y;
state.State = agent.type_map;
state.Health = agent.hp * (agent.max_hp > 0 ? agent.max_hp : 1);
state.Energy = agent.energy * (agent.max_energy > 0 ? agent.max_energy : 1);
states.push_back(state);
}
return states;
}
GameStatePayload GetPayload() {
GameStatePayload gamePayload;
if (!GW::Map::GetIsMapLoaded()) {
return gamePayload;
}
auto agents = GetLivingAgents();
if (agents.empty()) {
return gamePayload;
}
auto states = GetStates(agents);
gamePayload.States = states;
return gamePayload;
}
void EnsureInitialized() {
GameThreadMutex.lock();
if (!initialized) {
GW::GameThread::RegisterGameThreadCallback(&GameThreadHook, [&](GW::HookStatus*) {
while (!PromiseQueue.empty()) {
auto promise = PromiseQueue.front();
PromiseQueue.pop();
try {
auto payload = GetPayload();
promise->set_value(payload);
}
catch (...) {
GameStatePayload payload;
promise->set_value(payload);
}
}
});
initialized = true;
}
GameThreadMutex.unlock();
}
void GetGameStateInfo(const httplib::Request&, httplib::Response& res) {
auto callbackEntry = new GW::HookEntry;
auto response = new std::promise<GameStatePayload>;
EnsureInitialized();
PromiseQueue.emplace(response);
json responsePayload = response->get_future().get();
delete callbackEntry;
delete response;
res.set_content(responsePayload.dump(), "text/json");
}
}
+7
View File
@@ -0,0 +1,7 @@
#include "HttpLogger.h"
namespace http {
void ConsoleLogger(const httplib::Request req, httplib::Response res) {
std::cout << req.method << " " << req.path << std::endl << res.status << std::endl;
}
}
+116
View File
@@ -0,0 +1,116 @@
#include "pch.h"
#include "InventoryModule.h"
#include <GWCA/Managers/GameThreadMgr.h>
#include <GWCA/Managers/MapMgr.h>
#include <GWCA/Context/ItemContext.h>
#include <GWCA/Managers/ItemMgr.h>
#include <GWCA/GameEntities/Item.h>
#include <future>
#include <payloads/InventoryPayload.h>
#include <json.hpp>
#include <queue>
namespace Daybreak::Modules::InventoryModule {
std::queue<std::promise<InventoryPayload>*> PromiseQueue;
std::mutex GameThreadMutex;
GW::HookEntry GameThreadHook;
volatile bool initialized = false;
Daybreak::Bag GetBag(GW::Bag* bag) {
Bag retBag;
if (!bag) {
return retBag;
}
for (const auto &item : bag->items) {
BagContent bagContent;
if (!item) {
continue;
}
bagContent.Id = item->model_id;
bagContent.Slot = item->slot;
bagContent.Count = item->quantity;
auto modifier = item->mod_struct;
for (auto i = 0; i < item->mod_struct_size; i++) {
bagContent.Modifiers.push_back((uint32_t)(modifier->mod));
modifier++;
}
retBag.Items.push_back(bagContent);
}
return retBag;
}
InventoryPayload GetPayload() {
InventoryPayload inventoryPayload;
if (!GW::Map::GetIsMapLoaded()) {
return inventoryPayload;
}
inventoryPayload.GoldInStorage = GW::Items::GetGoldAmountInStorage();
inventoryPayload.GoldOnCharacter = GW::Items::GetGoldAmountOnCharacter();
auto inventory = GW::GetItemContext()->inventory;
inventoryPayload.Backpack = GetBag(inventory->backpack);
inventoryPayload.BeltPouch = (GetBag(inventory->belt_pouch));
inventoryPayload.Bags.push_back(GetBag(inventory->bag1));
inventoryPayload.Bags.push_back(GetBag(inventory->bag2));
inventoryPayload.EquipmentPack = (GetBag(inventory->equipment_pack));
inventoryPayload.MaterialStorage = (GetBag(inventory->material_storage));
inventoryPayload.UnclaimedItems = (GetBag(inventory->unclaimed_items));
inventoryPayload.EquippedItems = (GetBag(inventory->equipped_items));
inventoryPayload.StoragePanes.push_back(GetBag(inventory->storage1));
inventoryPayload.StoragePanes.push_back(GetBag(inventory->storage2));
inventoryPayload.StoragePanes.push_back(GetBag(inventory->storage3));
inventoryPayload.StoragePanes.push_back(GetBag(inventory->storage4));
inventoryPayload.StoragePanes.push_back(GetBag(inventory->storage5));
inventoryPayload.StoragePanes.push_back(GetBag(inventory->storage6));
inventoryPayload.StoragePanes.push_back(GetBag(inventory->storage7));
inventoryPayload.StoragePanes.push_back(GetBag(inventory->storage8));
inventoryPayload.StoragePanes.push_back(GetBag(inventory->storage9));
inventoryPayload.StoragePanes.push_back(GetBag(inventory->storage10));
inventoryPayload.StoragePanes.push_back(GetBag(inventory->storage11));
inventoryPayload.StoragePanes.push_back(GetBag(inventory->storage12));
inventoryPayload.StoragePanes.push_back(GetBag(inventory->storage13));
inventoryPayload.StoragePanes.push_back(GetBag(inventory->storage14));
return inventoryPayload;
}
void EnsureInitialized() {
GameThreadMutex.lock();
if (!initialized) {
GW::GameThread::RegisterGameThreadCallback(&GameThreadHook, [&](GW::HookStatus*) {
while (!PromiseQueue.empty()) {
auto promise = PromiseQueue.front();
PromiseQueue.pop();
try {
auto payload = GetPayload();
promise->set_value(payload);
}
catch(...){
InventoryPayload payload;
promise->set_value(payload);
}
}
});
initialized = true;
}
GameThreadMutex.unlock();
}
void GetInventoryInfo(const httplib::Request&, httplib::Response& res) {
auto callbackEntry = new GW::HookEntry;
auto response = new std::promise<InventoryPayload>;
EnsureInitialized();
PromiseQueue.emplace(response);
json responsePayload = response->get_future().get();
delete callbackEntry;
delete response;
res.set_content(responsePayload.dump(), "text/json");
}
}
+162
View File
@@ -0,0 +1,162 @@
#include "pch.h"
#include "ItemNameModule.h"
#include "payloads/NamePayload.h"
#include <GWCA/Managers/GameThreadMgr.h>
#include <GWCA/Managers/ItemMgr.h>
#include <GWCA/GameEntities/Item.h>
#include <future>
#include <json.hpp>
#include <tuple>
#include <queue>
#include <GWCA/GWCA.h>
#include <Windows.h>
#include <cstdint>
#include <limits>
#include <Utils.h>
namespace Daybreak::Modules::ItemNameModule {
std::vector<std::tuple<uint32_t, std::promise<NamePayload>*, std::wstring*>> WaitingList;
std::queue<std::tuple<uint32_t, std::vector<uint32_t>, std::promise<NamePayload>>*> PromiseQueue;
std::mutex GameThreadMutex;
GW::HookEntry GameThreadHook;
volatile bool initialized = false;
std::wstring* GetAsyncName(uint32_t id, std::vector<uint32_t> modifiers) {
GW::ItemModifier parsedModifiers[64];
for (auto i = 0; i < modifiers.size(); i++) {
GW::ItemModifier parsedModifier;
const auto mod = modifiers.at(i);
parsedModifier.mod = mod;
parsedModifiers[i] = parsedModifier;
}
auto item = GW::Items::GetItemByModelIdAndModifiers(id, parsedModifiers, modifiers.size(), 1, 23);
if (!item) {
return nullptr;
}
auto name = new std::wstring();
GW::Items::AsyncGetItemName(item, *name);
return name;
}
void EnsureInitialized() {
GameThreadMutex.lock();
if (!initialized) {
GW::GameThread::RegisterGameThreadCallback(&GameThreadHook, [&](GW::HookStatus*) {
while (!PromiseQueue.empty()) {
auto promiseRequest = PromiseQueue.front();
std::promise<NamePayload> &promise = std::get<2>(*promiseRequest);
uint32_t id = std::get<0>(*promiseRequest);
auto modifiers = std::get<1>(*promiseRequest);
PromiseQueue.pop();
try {
auto name = GetAsyncName(id, modifiers);
if (!name) {
continue;
}
WaitingList.emplace_back(id, &promise, name);
}
catch (...) {
NamePayload payload;
promise.set_value(payload);
}
}
for (size_t i = 0; i < WaitingList.size(); ) {
auto item = &WaitingList[i];
auto name = std::get<2>(*item);
if (name->empty()) {
i++;
continue;
}
auto promise = std::get<1>(*item);
auto id = std::get<0>(*item);
WaitingList.erase(WaitingList.begin() + i);
NamePayload payload;
payload.Id = id;
payload.Name = Daybreak::Utils::WStringToString(*name);
delete(name);
promise->set_value(payload);
}
});
initialized = true;
}
GameThreadMutex.unlock();
}
std::vector<std::string> SplitAndRemoveSpaces(const std::string& s) {
std::vector<std::string> result;
std::stringstream ss(s);
std::string item;
while (getline(ss, item, ',')) {
item.erase(std::remove(item.begin(), item.end(), ' '), item.end());
result.push_back(item);
}
return result;
}
void GetName(const httplib::Request& req, httplib::Response& res) {
auto callbackEntry = new GW::HookEntry;
uint32_t id = 0;
std::vector<uint32_t> modifiers;
auto id_it = req.params.find("id");
if (id_it == req.params.end()) {
res.status = 400;
res.set_content("Missing id parameter", "text/plain");
return;
}
else {
auto& idStr = id_it->second;
int parsedId;
if (!Daybreak::Utils::StringToInt(idStr, parsedId)){
res.status = 400;
res.set_content("Invalid id parameter", "text/plain");
return;
}
id = static_cast<uint32_t>(parsedId);
}
auto mod_it = req.params.find("modifiers");
if (mod_it == req.params.end()) {
res.status = 400;
res.set_content("Missing modifiers parameter", "text/plain");
return;
}
else {
auto& modifiersStr = mod_it->second;
const auto tokens = SplitAndRemoveSpaces(modifiersStr);
for (const auto& token : tokens) {
int parsedModifier;
if (!Daybreak::Utils::StringToInt(token, parsedModifier)) {
res.status = 400;
res.set_content("Invalid modifier parameter", "text/plain");
return;
}
modifiers.push_back(static_cast<uint32_t>(parsedModifier));
}
}
auto response = new std::tuple<uint32_t, std::vector<uint32_t>, std::promise<NamePayload>>();
std::get<0>(*response) = id;
std::promise<NamePayload>& promise = std::get<2>(*response);
std::get<1>(*response) = modifiers;
EnsureInitialized();
PromiseQueue.emplace(response);
json responsePayload = promise.get_future().get();
delete callbackEntry;
delete response;
res.set_content(responsePayload.dump(), "text/json");
}
}
+65
View File
@@ -0,0 +1,65 @@
#include "pch.h"
#include "LoginModule.h"
#include <GWCA/Managers/GameThreadMgr.h>
#include <GWCA/Managers/MapMgr.h>
#include <GWCA/Context/CharContext.h>
#include <future>
#include <payloads/LoginPayload.h>
#include <json.hpp>
#include <queue>
#include "Utils.h"
namespace Daybreak::Modules::LoginModule {
std::queue<std::promise<LoginPayload>*> PromiseQueue;
std::mutex GameThreadMutex;
GW::HookEntry GameThreadHook;
volatile bool initialized = false;
LoginPayload GetPayload() {
auto context = GW::GetCharContext();
LoginPayload loginPayload;
std::wstring playerEmail(context->player_email);
std::wstring playerName(context->player_name);
loginPayload.Email = Daybreak::Utils::WStringToString(playerEmail);
loginPayload.PlayerName = Daybreak::Utils::WStringToString(playerName);
return loginPayload;
}
void EnsureInitialized() {
GameThreadMutex.lock();
if (!initialized) {
GW::GameThread::RegisterGameThreadCallback(&GameThreadHook, [&](GW::HookStatus*) {
while (!PromiseQueue.empty()) {
auto promise = PromiseQueue.front();
PromiseQueue.pop();
try {
auto payload = GetPayload();
promise->set_value(payload);
}
catch (...) {
LoginPayload payload;
promise->set_value(payload);
}
}
});
initialized = true;
}
GameThreadMutex.unlock();
}
void GetLoginInfo(const httplib::Request&, httplib::Response& res) {
auto callbackEntry = new GW::HookEntry;
auto response = new std::promise<LoginPayload>;
EnsureInitialized();
PromiseQueue.emplace(response);
json responsePayload = response->get_future().get();
delete callbackEntry;
delete response;
res.set_content(responsePayload.dump(), "text/json");
}
}
+482
View File
@@ -0,0 +1,482 @@
#include "pch.h"
#include "MainPlayerModule.h"
#include <GWCA/Managers/GameThreadMgr.h>
#include <GWCA/Managers/MapMgr.h>
#include <GWCA/Managers/AgentMgr.h>
#include <GWCA/Managers/PartyMgr.h>
#include <GWCA/Managers/PlayerMgr.h>
#include <GWCA/Managers/SkillbarMgr.h>
#include <GWCA/Managers/QuestMgr.h>
#include <GWCA/Context/WorldContext.h>
#include <GWCA/GameContainers/Array.h>
#include <GWCA/GameEntities/Skill.h>
#include <GWCA/GameEntities/Quest.h>
#include <GWCA/GameEntities/Agent.h>
#include <GWCA/GameEntities/Title.h>
#include <GWCA/GameEntities/Party.h>
#include <GWCA/GameEntities/Attribute.h>
#include <GWCA/GameEntities/Player.h>
#include <GWCA/GameEntities/NPC.h>
#include <GWCA/Constants/Constants.h>
#include <temp/GWPlayer.h>
#include <future>
#include <payloads/MainPlayer.h>
#include <json.hpp>
#include <queue>
#include <algorithm>
#include "Utils.h"
namespace Daybreak::Modules::MainPlayerModule {
std::queue<std::promise<MainPlayer>*> PromiseQueue;
std::mutex GameThreadMutex;
GW::HookEntry GameThreadHook;
volatile bool initialized = false;
std::list<QuestMetadata> GetQuestLog() {
std::list<QuestMetadata> questMetadatas;
auto questLog = GW::QuestMgr::GetQuestLog();
if (!questLog) {
return questMetadatas;
}
for (auto& quest : *questLog) {
QuestMetadata metadata;
metadata.FromId = (uint32_t)quest.map_from;
metadata.ToId = (uint32_t)quest.map_to;
metadata.Id = (uint32_t)quest.quest_id;
metadata.PosX = quest.marker.x;
metadata.PosY = quest.marker.y;
questMetadatas.push_back(metadata);
}
return questMetadatas;
}
std::vector<GW::MapAgent> GetMapEntities() {
std::vector<GW::MapAgent> entities;
auto worldContext = GW::GetWorldContext();
for (auto& agent : worldContext->map_agents) {
entities.push_back(agent);
}
return entities;
}
std::list<GW::PartyAttribute> GetPartyAttributes() {
std::list<GW::PartyAttribute> attributes;
auto worldContext = GW::GetWorldContext();
for (auto& attribute : worldContext->attributes) {
attributes.push_back(attribute);
}
return attributes;
}
std::list<GW::ProfessionState> GetProfessions() {
std::list<GW::ProfessionState> professions;
auto worldContext = GW::GetWorldContext();
for (auto& profession : worldContext->party_profession_states) {
professions.push_back(profession);
}
return professions;
}
std::list<GW::AgentLiving> GetLivingAgents() {
std::list<GW::AgentLiving> agentList;
const GW::AgentArray* agents_ptr = GW::Agents::GetAgentArray();
GW::AgentArray* agents = GW::Agents::GetAgentArray();
if (!agents) {
return agentList;
}
for (auto* a : *agents) {
const GW::AgentLiving* agent = a ? a->GetAsAgentLiving() : nullptr;
if (agent) {
agentList.push_back(*agent);
}
}
return agentList;
}
std::list<GW::NPC> GetNpcs() {
std::list<GW::NPC> npcs;
auto worldContext = GW::GetWorldContext();
for (auto& npc : worldContext->npcs) {
npcs.push_back(npc);
}
return npcs;
}
std::vector<GW::TitleTier> GetTitleTiers() {
std::vector<GW::TitleTier> titles;
auto worldContext = GW::GetWorldContext();
for (auto& title : worldContext->title_tiers) {
titles.push_back(title);
}
return titles;
}
std::list<GW::Title> GetTitles() {
std::list<GW::Title> titles;
auto worldContext = GW::GetWorldContext();
for (auto& title : worldContext->titles) {
titles.push_back(title);
}
return titles;
}
std::list<Temp::GWPlayer> GetPlayers() {
std::list<Temp::GWPlayer> players;
auto worldContext = GW::GetWorldContext();
Temp::GWPlayer *tempPlayerArray = (Temp::GWPlayer*)worldContext->players.m_buffer;
if (!tempPlayerArray) {
return players;
}
for (auto i = 0; i < worldContext->players.m_size; i++) {
if (tempPlayerArray->agent_id != 0) {
players.push_back(*tempPlayerArray);
}
tempPlayerArray++;
}
return players;
}
std::map<uint32_t, std::list<uint32_t>> GetSkillbars() {
std::map<uint32_t, std::list<uint32_t>> skillbarMap;
auto skillbars = GW::SkillbarMgr::GetSkillbarArray();
if (!skillbars) {
return skillbarMap;
}
for (auto& skillbar : *skillbars) {
std::list<uint32_t> skillList;
skillList.push_back((uint32_t)skillbar.skills[0].skill_id);
skillList.push_back((uint32_t)skillbar.skills[1].skill_id);
skillList.push_back((uint32_t)skillbar.skills[2].skill_id);
skillList.push_back((uint32_t)skillbar.skills[3].skill_id);
skillList.push_back((uint32_t)skillbar.skills[4].skill_id);
skillList.push_back((uint32_t)skillbar.skills[5].skill_id);
skillList.push_back((uint32_t)skillbar.skills[6].skill_id);
skillList.push_back((uint32_t)skillbar.skills[7].skill_id);
skillbarMap[skillbar.agent_id] = skillList;
}
return skillbarMap;
}
std::list<LivingEntity> GetLivingEntities(
std::list<GW::AgentLiving> agents) {
std::list<LivingEntity> entities;
for (auto& agent : agents) {
LivingEntity entity;
entity.PrimaryProfessionId = agent.primary;
entity.SecondaryProfessionId = agent.secondary;
entity.EntityState = agent.type_map;
entity.EntityAllegiance = (uint32_t)agent.allegiance;
entity.NpcDefinition = agent.player_number;
entity.Id = agent.agent_id;
entity.Timer = agent.timer;
entity.Level = agent.level;
entity.PosX = agent.pos.x;
entity.PosY = agent.pos.y;
entities.push_back(entity);
}
return entities;
}
void PopulatePlayer(
Player& player,
int playerId,
GW::ProfessionState* professionState,
std::list<uint32_t> skillbar,
GW::PartyAttribute* partyAttribute,
GW::AgentLiving* agent) {
std::list<uint32_t> unlockedProfessions;
if (professionState) {
for (auto i = 0; i < 11; i++) {
auto prof = (GW::Constants::Profession)i;
if (professionState->IsProfessionUnlocked(prof)) {
unlockedProfessions.push_back(i);
}
}
unlockedProfessions.push_back((uint32_t)professionState->primary);
}
Build build;
std::list<Attribute> attributes;
if (partyAttribute) {
for (const auto& partyAttr : partyAttribute->attribute) {
if (((uint32_t)partyAttr.id < 0) ||
((uint32_t)partyAttr.id > 44) ||
partyAttr.level <= 0) {
continue;
}
Attribute attribute;
attribute.Id = (uint32_t)partyAttr.id;
attribute.BaseLevel = partyAttr.level_base;
attribute.ActualLevel = partyAttr.level;
attribute.DecrementPoints = partyAttr.decrement_points;
attribute.IncrementPoints = partyAttr.increment_points;
attributes.push_back(attribute);
}
build.Attributes = attributes;
if (agent) {
build.Primary = (uint32_t)agent->primary;
build.Secondary = (uint32_t)agent->secondary;
}
else if (professionState) {
build.Primary = (uint32_t)professionState->primary;
build.Secondary = (uint32_t)professionState->secondary;
}
build.Skills = skillbar;
player.Build = build;
}
player.UnlockedProfession = unlockedProfessions;
player.Id = playerId;
if (agent) {
player.PosX = agent->pos.x;
player.PosY = agent->pos.y;
player.Timer = agent->timer;
player.Level = agent->level;
player.NpcDefinition = agent->player_number;
player.PrimaryProfessionId = (uint32_t)agent->primary;
player.SecondaryProfessionId = (uint32_t)agent->secondary;
player.Health = agent->hp * (agent->max_hp > 0 ? agent->max_hp : 1);
player.Energy = agent->energy * (agent->max_energy > 0 ? agent->max_energy : 1);
}
else if (professionState) {
player.PrimaryProfessionId = (uint32_t)professionState->primary;
player.SecondaryProfessionId = (uint32_t)professionState->secondary;
}
}
void PopulateWorldPlayer(
std::list<GW::Title> titles,
std::vector<GW::TitleTier> titleTiers,
WorldPlayer& player,
int playerId,
Temp::GWPlayer* gwPlayer,
GW::ProfessionState* professionState,
std::list<uint32_t> skillbar,
GW::PartyAttribute* partyAttribute,
GW::AgentLiving* agent) {
PopulatePlayer(player, playerId, professionState, skillbar, partyAttribute, agent);
if (!gwPlayer) {
return;
}
GW::Title gwTitle;
Title title;
int titleId = 0;
std::wstring gwPlayerName(gwPlayer->name);
auto name = Daybreak::Utils::WStringToString(gwPlayerName);
player.Name = name;
for (const auto &t : titles) {
if (t.current_title_tier_index == gwPlayer->active_title_tier) {
gwTitle = t;
break;
}
titleId++;
}
if (gwTitle.current_title_tier_index >= titleTiers.size()) {
return;
}
auto titleTier = titleTiers[gwTitle.current_title_tier_index];
title.CurrentPoints = gwTitle.current_points;
title.IsPercentage = gwTitle.is_percentage_based();
title.PointsForCurrentRank = gwTitle.points_needed_current_rank;
title.PointsForNextRank = titleTier.tier_number == gwTitle.max_title_rank ? gwTitle.current_points : gwTitle.points_needed_next_rank;
title.TierNumber = titleTier.tier_number;
title.MaxTierNumber = gwTitle.max_title_rank;
title.Id = titleId;
player.Title = title;
}
void PopulateMainPlayer(
MainPlayer& player,
int activeQuestId,
std::list<QuestMetadata> questLog,
std::list<GW::Title> titles,
std::vector<GW::TitleTier> titleTiers,
int playerId,
Temp::GWPlayer* gwPlayer,
GW::ProfessionState* professionState,
std::list<uint32_t> skillbar,
GW::PartyAttribute* partyAttribute,
GW::AgentLiving* agent) {
PopulateWorldPlayer(titles, titleTiers, player, playerId, gwPlayer, professionState, skillbar, partyAttribute, agent);
player.CurrentQuest = activeQuestId;
player.QuestLog = questLog;
player.HardModeUnlocked = GW::GetWorldContext()->is_hard_mode_unlocked == 1;
player.Experience = GW::GetWorldContext()->experience;
player.Morale = GW::GetWorldContext()->morale;
if (agent) {
player.CurrentEnergy = agent->max_energy * agent->energy;
player.CurrentHp = agent->max_hp * agent->hp;
player.MaxEnergy = agent->max_energy;
player.MaxHp = agent->max_hp;
}
}
MainPlayer GetPayload() {
MainPlayer gamePayload;
if (!GW::Map::GetIsMapLoaded()) {
return gamePayload;
}
auto worldContext = GW::GetWorldContext();
auto activeQuestId = GW::QuestMgr::GetActiveQuestId();
auto questLog = GetQuestLog();
auto skillbars = GetSkillbars();
if (skillbars.empty()) {
return gamePayload;
}
auto agents = GetLivingAgents();
if (agents.empty()) {
return gamePayload;
}
auto titles = GetTitles();
if (titles.empty()) {
return gamePayload;
}
auto titleTiers = GetTitleTiers();
if (titleTiers.empty()) {
return gamePayload;
}
auto players = GetPlayers();
if (players.empty()) {
return gamePayload;
}
auto npcs = GetNpcs();
if (npcs.empty()) {
return gamePayload;
}
auto attributes = GetPartyAttributes();
if (attributes.empty()) {
return gamePayload;
}
auto professions = GetProfessions();
if (professions.empty()) {
return gamePayload;
}
auto mapAgents = GetMapEntities();
if (mapAgents.empty()) {
return gamePayload;
}
auto playerAgentId = GW::Agents::GetPlayerId();
MainPlayer mainPlayer;
auto foundMainAttr = std::find_if(attributes.begin(), attributes.end(), [&](GW::PartyAttribute attribute) {
return playerAgentId == attribute.agent_id;
});
auto foundMainAgent = std::find_if(agents.begin(), agents.end(), [&](GW::AgentLiving agentLiving) {
return playerAgentId == agentLiving.agent_id;
});
auto foundMainProfessionsState = std::find_if(professions.begin(), professions.end(), [&](GW::ProfessionState professionState) {
return playerAgentId == professionState.agent_id;
});
auto foundMainGwPlayer = std::find_if(players.begin(), players.end(), [&](Temp::GWPlayer gwPlayer) {
return playerAgentId == gwPlayer.agent_id;
});
GW::AgentLiving* mainAgentPtr;
if (foundMainAgent == agents.end()) {
mainAgentPtr = nullptr;
}
else {
mainAgentPtr = &*foundMainAgent;
}
GW::PartyAttribute* mainAttrPtr;
if (foundMainAttr == attributes.end()) {
mainAttrPtr = nullptr;
}
else {
mainAttrPtr = &*foundMainAttr;
}
GW::ProfessionState* mainProfPtr;
if (foundMainProfessionsState == professions.end()) {
mainProfPtr = nullptr;
}
else {
mainProfPtr = &*foundMainProfessionsState;
}
Temp::GWPlayer* mainGwPlayer;
if (foundMainGwPlayer == players.end()) {
mainGwPlayer = nullptr;
}
else {
mainGwPlayer = &*foundMainGwPlayer;
}
PopulateMainPlayer(mainPlayer, (uint32_t)activeQuestId, questLog, titles, titleTiers, playerAgentId, mainGwPlayer, mainProfPtr, skillbars[playerAgentId], mainAttrPtr, mainAgentPtr);
return mainPlayer;
}
void EnsureInitialized() {
GameThreadMutex.lock();
if (!initialized) {
GW::GameThread::RegisterGameThreadCallback(&GameThreadHook, [&](GW::HookStatus*) {
while (!PromiseQueue.empty()) {
auto promise = PromiseQueue.front();
PromiseQueue.pop();
try {
auto payload = GetPayload();
promise->set_value(payload);
}
catch (...) {
MainPlayer payload;
promise->set_value(payload);
}
}
});
initialized = true;
}
GameThreadMutex.unlock();
}
void GetMainPlayer(const httplib::Request&, httplib::Response& res) {
auto callbackEntry = new GW::HookEntry;
auto response = new std::promise<MainPlayer>;
EnsureInitialized();
PromiseQueue.emplace(response);
json responsePayload = response->get_future().get();
delete callbackEntry;
delete response;
res.set_content(responsePayload.dump(), "text/json");
}
}
+72
View File
@@ -0,0 +1,72 @@
#include "pch.h"
#include "MapModule.h"
#include <GWCA/Managers/GameThreadMgr.h>
#include <GWCA/Managers/MapMgr.h>
#include <future>
#include <payloads/MapPayload.h>
#include <json.hpp>
#include <queue>
namespace Daybreak::Modules::MapModule {
std::queue<std::promise<MapPayload>*> PromiseQueue;
std::mutex GameThreadMutex;
GW::HookEntry GameThreadHook;
volatile bool initialized = false;
MapPayload GetPayload() {
auto isLoaded = GW::Map::GetIsMapLoaded();
auto instanceType = GW::Map::GetInstanceType();
auto instanceTime = GW::Map::GetInstanceTime();
auto mapInfo = GW::Map::GetCurrentMapInfo();
auto isInCinematic = GW::Map::GetIsInCinematic();
auto region = GW::Map::GetRegion();
auto mapId = GW::Map::GetMapID();
MapPayload mapPayload;
mapPayload.Campaign = mapInfo->campaign;
mapPayload.Continent = mapInfo->continent;
mapPayload.Region = mapInfo->region;
mapPayload.InstanceType = (uint32_t)instanceType;
mapPayload.IsLoaded = isLoaded;
mapPayload.Timer = instanceTime;
mapPayload.Id = (uint32_t)mapId;
return mapPayload;
}
void EnsureInitialized() {
GameThreadMutex.lock();
if (!initialized) {
GW::GameThread::RegisterGameThreadCallback(&GameThreadHook, [&](GW::HookStatus*) {
while (!PromiseQueue.empty()) {
auto promise = PromiseQueue.front();
PromiseQueue.pop();
try {
auto payload = GetPayload();
promise->set_value(payload);
}
catch (...) {
MapPayload payload;
promise->set_value(payload);
}
}
});
initialized = true;
}
GameThreadMutex.unlock();
}
void GetMapInfo(const httplib::Request&, httplib::Response& res) {
auto callbackEntry = new GW::HookEntry;
auto response = new std::promise<MapPayload>;
EnsureInitialized();
PromiseQueue.emplace(response);
json responsePayload = response->get_future().get();
delete callbackEntry;
delete response;
res.set_content(responsePayload.dump(), "text/json");
}
}
@@ -0,0 +1,71 @@
#include "pch.h"
#include "PathingMetadataModule.h"
#include <GWCA/Managers/GameThreadMgr.h>
#include <GWCA/Managers/MapMgr.h>
#include <future>
#include <payloads/PathingMetadataPayload.h>
#include <json.hpp>
#include <queue>
#include <GWCA/GameEntities/Pathing.h>
namespace Daybreak::Modules::PathingMetadataModule {
std::queue<std::promise<PathingMetadataPayload>*> PromiseQueue;
std::mutex GameThreadMutex;
GW::HookEntry GameThreadHook;
volatile bool initialized = false;
PathingMetadataPayload GetPayload() {
PathingMetadataPayload pathingPayload;
pathingPayload.TrapezoidCount = 0;
if (!GW::Map::GetIsMapLoaded()) {
return pathingPayload;
}
auto pathingMap = GW::Map::GetPathingMap();
int count = 0;
for (int i = 0; i < pathingMap->size(); i++) {
auto gwPathingMap = pathingMap->at(i);
count += gwPathingMap.trapezoid_count;
}
pathingPayload.TrapezoidCount = count;
return pathingPayload;
}
void EnsureInitialized() {
GameThreadMutex.lock();
if (!initialized) {
GW::GameThread::RegisterGameThreadCallback(&GameThreadHook, [&](GW::HookStatus*) {
while (!PromiseQueue.empty()) {
auto promise = PromiseQueue.front();
PromiseQueue.pop();
try {
auto payload = GetPayload();
promise->set_value(payload);
}
catch (...) {
PathingMetadataPayload payload;
promise->set_value(payload);
}
}
});
initialized = true;
}
GameThreadMutex.unlock();
}
void GetPathingMetadata(const httplib::Request&, httplib::Response& res) {
auto callbackEntry = new GW::HookEntry;
auto response = new std::promise<PathingMetadataPayload>;
EnsureInitialized();
PromiseQueue.emplace(response);
json responsePayload = response->get_future().get();
delete callbackEntry;
delete response;
res.set_content(responsePayload.dump(), "text/json");
}
}
+98
View File
@@ -0,0 +1,98 @@
#include "pch.h"
#include "PathingModule.h"
#include <GWCA/Managers/GameThreadMgr.h>
#include <GWCA/Managers/MapMgr.h>
#include <future>
#include <payloads/PathingPayload.h>
#include <json.hpp>
#include <queue>
#include <GWCA/GameEntities/Pathing.h>
namespace Daybreak::Modules::PathingModule {
std::queue<std::promise<PathingPayload>*> PromiseQueue;
std::mutex GameThreadMutex;
GW::HookEntry GameThreadHook;
volatile bool initialized = false;
PathingPayload GetPayload() {
PathingPayload pathingPayload;
pathingPayload.Trapezoids.clear();
pathingPayload.AdjacencyList.clear();
if (!GW::Map::GetIsMapLoaded()) {
return pathingPayload;
}
auto pathingMap = GW::Map::GetPathingMap();
std::list<PathingTrapezoid> trapezoids;
std::map<int, std::list<int>> adjacencyMap;
for (int i = 0; i < pathingMap->size(); i++) {
auto gwPathingMap = pathingMap->at(i);
for (int j = 0; j < gwPathingMap.trapezoid_count; j++) {
auto gwTrapezoid = gwPathingMap.trapezoids[j];
PathingTrapezoid trapezoid;
trapezoid.Id = gwTrapezoid.id;
trapezoid.PathingMapId = i;
trapezoid.XTL = gwTrapezoid.XTL;
trapezoid.XBL = gwTrapezoid.XBL;
trapezoid.XTR = gwTrapezoid.XTR;
trapezoid.XBR = gwTrapezoid.XBR;
trapezoid.YT = gwTrapezoid.YT;
trapezoid.YB = gwTrapezoid.YB;
trapezoids.push_back(trapezoid);
for (int k = 0; k < 4; k++) {
auto adjacentTrapezoid = gwTrapezoid.adjacent[k];
if (adjacentTrapezoid) {
adjacencyMap[trapezoid.Id].push_back(adjacentTrapezoid->id);
}
}
}
}
std::list<std::list<int>> adjacencyList;
for (const auto& pair : adjacencyMap) {
adjacencyList.push_back(pair.second);
}
pathingPayload.Trapezoids = trapezoids;
pathingPayload.AdjacencyList = adjacencyList;
return pathingPayload;
}
void EnsureInitialized() {
GameThreadMutex.lock();
if (!initialized) {
GW::GameThread::RegisterGameThreadCallback(&GameThreadHook, [&](GW::HookStatus*) {
while (!PromiseQueue.empty()) {
auto promise = PromiseQueue.front();
PromiseQueue.pop();
try {
auto payload = GetPayload();
promise->set_value(payload);
}
catch (...) {
PathingPayload payload;
promise->set_value(payload);
}
}
});
initialized = true;
}
GameThreadMutex.unlock();
}
void GetPathingData(const httplib::Request&, httplib::Response& res) {
auto callbackEntry = new GW::HookEntry;
auto response = new std::promise<PathingPayload>;
EnsureInitialized();
PromiseQueue.emplace(response);
json responsePayload = response->get_future().get();
delete callbackEntry;
delete response;
res.set_content(responsePayload.dump(), "text/json");
}
}
+74
View File
@@ -0,0 +1,74 @@
#include "pch.h"
#include "MapModule.h"
#include <GWCA/Managers/GameThreadMgr.h>
#include <GWCA/Managers/MapMgr.h>
#include <future>
#include <payloads/PreGamePayload.h>
#include <json.hpp>
#include <queue>
#include <GWCA/GWCA.h>
#include <GWCA/Context/PreGameContext.h>
namespace Daybreak::Modules::PreGameModule {
std::queue<std::promise<PreGamePayload>*> PromiseQueue;
std::mutex GameThreadMutex;
GW::HookEntry GameThreadHook;
volatile bool initialized = false;
PreGamePayload GetPayload() {
PreGamePayload preGamePayload;
if (GW::Map::GetIsMapLoaded()) {
preGamePayload.Characters.clear();
preGamePayload.ChosenCharacterIndex = 0;
return preGamePayload;
}
auto context = GW::GetPreGameContext();
for (const auto& loginChar : context->chars) {
std::string charName(20, '\0');
auto length = std::wcstombs(&charName[0], loginChar.character_name, 20);
charName.resize(length);
preGamePayload.Characters.push_back(charName);
}
preGamePayload.ChosenCharacterIndex = context->index_1;
return preGamePayload;
}
void EnsureInitialized() {
GameThreadMutex.lock();
if (!initialized) {
GW::GameThread::RegisterGameThreadCallback(&GameThreadHook, [&](GW::HookStatus*) {
while (!PromiseQueue.empty()) {
auto promise = PromiseQueue.front();
PromiseQueue.pop();
try {
auto payload = GetPayload();
promise->set_value(payload);
}
catch (...) {
PreGamePayload payload;
promise->set_value(payload);
}
}
});
initialized = true;
}
GameThreadMutex.unlock();
}
void GetPreGameInfo(const httplib::Request&, httplib::Response& res) {
auto callbackEntry = new GW::HookEntry;
auto response = new std::promise<PreGamePayload>;
EnsureInitialized();
PromiseQueue.emplace(response);
json responsePayload = response->get_future().get();
delete callbackEntry;
delete response;
res.set_content(responsePayload.dump(), "text/json");
}
}
+21
View File
@@ -0,0 +1,21 @@
#include "pch.h"
#include "ProcessIdModule.h"
namespace http {
namespace modules {
static DWORD processId = 0;
int GetProcessId() {
if (processId > 0) {
return processId;
}
processId = GetCurrentProcessId();
return processId;
}
void HandleProcessId(const httplib::Request&, httplib::Response& res) {
res.set_content(std::to_string(GetProcessId()), "text/plain");
}
}
}
+76
View File
@@ -0,0 +1,76 @@
#include "pch.h"
#include "Server.h"
namespace http {
namespace server {
static httplib::Server server;
static int FindPort() {
// Initialize Winsock
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
std::cout << "Failed to initialize Winsock." << std::endl;
return -1;
}
// Create a socket
SOCKET serverSocket = socket(AF_INET, SOCK_STREAM, 0);
if (serverSocket == INVALID_SOCKET) {
std::cout << "Failed to create socket." << std::endl;
return -1;
}
sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = INADDR_ANY;
// Start from a specific port number and find an available port
int port = 48557;
while (true) {
serverAddr.sin_port = htons(port);
if (bind(serverSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == 0) {
std::cout << "Successfully bound to port " << port << std::endl;
break;
}
else {
port++; // Try the next port
}
if (port > 65534) {
std::cout << "Failed to find a port. Cannot initialize server" << std::endl;
return -1;
}
}
// Clean up
closesocket(serverSocket);
WSACleanup();
return port;
}
void Get(const std::string& pattern, httplib::Server::Handler handler) {
server.Get(pattern, handler);
}
void SetLogger(httplib::Logger logger) {
server.set_logger(logger);
}
bool StartServer() {
int port = FindPort();
if (port > 0) {
std::cout << "Initializing server on port " << port << std::endl;
server.listen("0.0.0.0", port);
return true;
}
return false;
}
void StopServer() {
server.stop();
}
}
}
+76
View File
@@ -0,0 +1,76 @@
#include "pch.h"
#include "SessionModule.h"
#include <GWCA/Managers/GameThreadMgr.h>
#include <GWCA/Managers/MapMgr.h>
#include <future>
#include <payloads/SessionPayload.h>
#include <json.hpp>
#include <queue>
#include <GWCA/Context/AgentContext.h>
#include <GWCA/Context/WorldContext.h>
namespace Daybreak::Modules::SessionModule {
std::queue<std::promise<SessionPayload>*> PromiseQueue;
std::mutex GameThreadMutex;
GW::HookEntry GameThreadHook;
volatile bool initialized = false;
SessionPayload GetPayload() {
SessionPayload sessionPayload;
sessionPayload.MapId = (uint32_t)GW::Map::GetMapID();
sessionPayload.InstanceType = (uint32_t)GW::Map::GetInstanceType();
const auto worldContext = GW::GetWorldContext();
if (!worldContext) {
return sessionPayload;
}
sessionPayload.FoesKilled = worldContext->foes_killed;
sessionPayload.FoesToKill = worldContext->foes_to_kill;
const auto agentContext = GW::GetAgentContext();
if (!agentContext) {
return sessionPayload;
}
sessionPayload.InstanceTimer = agentContext->instance_timer;
return sessionPayload;
}
void EnsureInitialized() {
GameThreadMutex.lock();
if (!initialized) {
GW::GameThread::RegisterGameThreadCallback(&GameThreadHook, [&](GW::HookStatus*) {
while (!PromiseQueue.empty()) {
auto promise = PromiseQueue.front();
PromiseQueue.pop();
try {
auto payload = GetPayload();
promise->set_value(payload);
}
catch (...) {
SessionPayload payload;
promise->set_value(payload);
}
}
});
initialized = true;
}
GameThreadMutex.unlock();
}
void GetSessionInfo(const httplib::Request&, httplib::Response& res) {
auto callbackEntry = new GW::HookEntry;
auto response = new std::promise<SessionPayload>;
EnsureInitialized();
PromiseQueue.emplace(response);
json responsePayload = response->get_future().get();
delete callbackEntry;
delete response;
res.set_content(responsePayload.dump(), "text/json");
}
}
+80
View File
@@ -0,0 +1,80 @@
#include "pch.h"
#include "UserModule.h"
#include <GWCA/Managers/GameThreadMgr.h>
#include <GWCA/Managers/MapMgr.h>
#include <future>
#include <payloads/UserPayload.h>
#include <json.hpp>
#include <queue>
#include <GWCA/Context/CharContext.h>
#include <GWCA/Context/WorldContext.h>
namespace Daybreak::Modules::UserModule {
std::queue<std::promise<UserPayload>*> PromiseQueue;
std::mutex GameThreadMutex;
GW::HookEntry GameThreadHook;
volatile bool initialized = false;
UserPayload GetPayload() {
UserPayload userPayload;
auto charContext = GW::GetCharContext();
auto worldContext = GW::GetWorldContext();
std::string emailstr(64, '\0');
auto length = std::wcstombs(&emailstr[0], charContext->player_email, 64);
emailstr.resize(length);
userPayload.Email = emailstr;
userPayload.CurrentKurzickPoints = worldContext->current_kurzick;
userPayload.CurrentLuxonPoints = worldContext->current_luxon;
userPayload.CurrentImperialPoints = worldContext->current_imperial;
userPayload.CurrentBalthazarPoints = worldContext->current_balth;
userPayload.CurrentSkillPoints = worldContext->current_skill_points;
userPayload.TotalKurzickPoints = worldContext->total_earned_kurzick;
userPayload.TotalLuxonPoints = worldContext->total_earned_luxon;
userPayload.TotalImperialPoints = worldContext->total_earned_imperial;
userPayload.TotalBalthazarPoints = worldContext->total_earned_balth;
userPayload.TotalSkillPoints = worldContext->total_earned_skill_points;
userPayload.MaxKurzickPoints = worldContext->max_kurzick;
userPayload.MaxLuxonPoints = worldContext->max_luxon;
userPayload.MaxImperialPoints = worldContext->max_imperial;
userPayload.MaxBalthazarPoints = worldContext->max_balth;
return userPayload;
}
void EnsureInitialized() {
GameThreadMutex.lock();
if (!initialized) {
GW::GameThread::RegisterGameThreadCallback(&GameThreadHook, [&](GW::HookStatus*) {
while (!PromiseQueue.empty()) {
auto promise = PromiseQueue.front();
PromiseQueue.pop();
try {
auto payload = GetPayload();
promise->set_value(payload);
}
catch (...) {
UserPayload payload;
promise->set_value(payload);
}
}
});
initialized = true;
}
GameThreadMutex.unlock();
}
void GetUserInfo(const httplib::Request&, httplib::Response& res) {
auto callbackEntry = new GW::HookEntry;
auto response = new std::promise<UserPayload>;
EnsureInitialized();
PromiseQueue.emplace(response);
json responsePayload = response->get_future().get();
delete callbackEntry;
delete response;
res.set_content(responsePayload.dump(), "text/json");
}
}
+32
View File
@@ -0,0 +1,32 @@
#include "pch.h"
#include <iostream>
#include <limits>
#include <windows.h>
#include <string>
#include <cstdint>
namespace Daybreak::Utils {
std::string WStringToString(const std::wstring& wstr)
{
if (wstr.empty()) return std::string();
int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL);
std::string strTo(size_needed, 0);
WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL);
return strTo;
}
bool StringToInt(const std::string& str, int& outValue) {
size_t pos = 0;
unsigned long result = std::stoul(str, &pos);
// Ensure the entire string was processed
if (pos != str.size()) {
return false;
}
outValue = static_cast<int>(result);
return true;
}
}
+161
View File
@@ -0,0 +1,161 @@
// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include "httplib.h"
#include <GWCA/GWCA.h>
#include <GWCA/Utilities/Scanner.h>
#include <GWCA/Utilities/Hook.h>
#include <GWCA/Utilities/Hooker.h>
#include <GWCA/Managers/RenderMgr.h>
#include <GWCA/Managers/MemoryMgr.h>
#include "AliveModule.h"
#include "ProcessIdModule.h"
#include "HttpLogger.h"
#include "Server.h"
#include "MapModule.h"
#include "LoginModule.h"
#include "PathingMetadataModule.h"
#include "PathingModule.h"
#include "PreGameModule.h"
#include "InventoryModule.h"
#include "UserModule.h"
#include "GameModule.h"
#include "MainPlayerModule.h"
#include "SessionModule.h"
#include "EntityNameModule.h"
#include "GameStateModule.h"
#include "ItemNameModule.h"
#include <mutex>
volatile bool initialized;
volatile WNDPROC oldWndProc;
std::mutex startupMutex;
HMODULE dllmodule;
HANDLE serverThread;
static FILE* stdout_proxy;
static FILE* stderr_proxy;
void Terminate()
{
http::server::StopServer();
if (serverThread) {
CloseHandle(serverThread);
}
#ifdef BUILD_TYPE_DEBUG
if (stdout_proxy)
fclose(stdout_proxy);
if (stderr_proxy)
fclose(stderr_proxy);
FreeConsole();
#endif
}
static DWORD WINAPI StartHttpServer(LPVOID)
{
// This is a new thread so you should only initialize GWCA and setup the hook on the game thread.
// When the game thread hook is setup (i.e. SetRenderCallback), you should do the next operations
// on the game from within the game thread.
http::server::SetLogger(http::ConsoleLogger);
http::server::Get("/alive", http::modules::HandleAlive);
http::server::Get("/id", http::modules::HandleProcessId);
http::server::Get("/map", Daybreak::Modules::MapModule::GetMapInfo);
http::server::Get("/login", Daybreak::Modules::LoginModule::GetLoginInfo);
http::server::Get("/pathing/metadata", Daybreak::Modules::PathingMetadataModule::GetPathingMetadata);
http::server::Get("/pathing", Daybreak::Modules::PathingModule::GetPathingData);
http::server::Get("/pregame", Daybreak::Modules::PreGameModule::GetPreGameInfo);
http::server::Get("/user", Daybreak::Modules::UserModule::GetUserInfo);
http::server::Get("/game", Daybreak::Modules::GameModule::GetGameInfo);
http::server::Get("/inventory", Daybreak::Modules::InventoryModule::GetInventoryInfo);
http::server::Get("/game/mainplayer", Daybreak::Modules::MainPlayerModule::GetMainPlayer);
http::server::Get("/game/state", Daybreak::Modules::GameStateModule::GetGameStateInfo);
http::server::Get("/session", Daybreak::Modules::SessionModule::GetSessionInfo);
http::server::Get("/entities/name", Daybreak::Modules::EntityNameModule::GetName);
http::server::Get("/items/name", Daybreak::Modules::ItemNameModule::GetName);
http::server::StartServer();
return 0;
}
LRESULT CALLBACK WndProc(const HWND hWnd, const UINT Message, const WPARAM wParam, const LPARAM lParam) {
if (Message == WM_CLOSE || (Message == WM_SYSCOMMAND && wParam == SC_CLOSE)) {
Terminate();
}
return CallWindowProc(oldWndProc, hWnd, Message, wParam, lParam);
}
LRESULT CALLBACK SafeWndProc(const HWND hWnd, const UINT Message, const WPARAM wParam, const LPARAM lParam) noexcept
{
__try {
return WndProc(hWnd, Message, wParam, lParam);
}
__except (EXCEPTION_EXECUTE_HANDLER) {
return CallWindowProc(oldWndProc, hWnd, Message, wParam, lParam);
}
}
void OnWindowCreated(IDirect3DDevice9*) {
startupMutex.lock();
if (initialized) {
startupMutex.unlock();
return;
}
#ifdef BUILD_TYPE_DEBUG
AllocConsole();
SetConsoleTitleA("Daybreak.GWCA Console");
freopen_s(&stdout_proxy, "CONOUT$", "w", stdout);
freopen_s(&stderr_proxy, "CONOUT$", "w", stderr);
#endif
auto handle = GW::MemoryMgr::GetGWWindowHandle();
oldWndProc = reinterpret_cast<WNDPROC>(SetWindowLongPtrW(handle, GWL_WNDPROC, reinterpret_cast<LONG>(SafeWndProc)));
serverThread = CreateThread(
NULL,
0,
StartHttpServer,
NULL,
0,
NULL);
startupMutex.unlock();
initialized = true;
return;
}
static DWORD WINAPI Init(LPVOID)
{
printf("Init: Setting up scanner\n");
GW::Scanner::Initialize();
printf("Init: Setting up hook base\n");
GW::HookBase::Initialize();
printf("Init: Setting up GWCA\n");
if (!GW::Initialize()) {
printf("Init: Failed to set up GWCA\n");
return 0;
}
printf("Init: Enabling hooks\n");
GW::HookBase::EnableHooks();
printf("Init: Set up render callback\n");
GW::Render::SetRenderCallback(OnWindowCreated);
printf("Init: Returning success\n");
FreeLibraryAndExitThread(dllmodule, EXIT_SUCCESS);
return 0;
}
// DLL entry point, dont do things in this thread unless you know what you are doing.
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
DisableThreadLibraryCalls(hModule);
if (ul_reason_for_call == DLL_PROCESS_ATTACH) {
HANDLE handle = CreateThread(0, 0, Init, hModule, 0, 0);
CloseHandle(handle);
}
return TRUE;
}
@@ -0,0 +1,18 @@
#include <cstdint>
#include <payloads/Attribute.h>
#include <json.hpp>
using json = nlohmann::json;
namespace Daybreak {
void to_json(json& j, const Attribute& p) {
j = json
{
{"Id", p.Id},
{"BaseLevel", p.BaseLevel},
{"ActualLevel", p.ActualLevel},
{"DecrementPoints", p.DecrementPoints},
{"IncrementPoints", p.IncrementPoints},
};
}
}
+16
View File
@@ -0,0 +1,16 @@
#pragma once
#include <cstdint>
#include <payloads/BagContent.h>
#include <payloads/Bag.h>
#include <json.hpp>
using json = nlohmann::json;
namespace Daybreak {
void to_json(json& j, const Bag& p) {
j = json
{
{"Items", p.Items},
};
}
}
@@ -0,0 +1,19 @@
#pragma once
#include <cstdint>
#include <GWCA/GameEntities/Map.h>
#include <payloads/BagContent.h>
#include <json.hpp>
using json = nlohmann::json;
namespace Daybreak {
void to_json(json& j, const BagContent& p) {
j = json
{
{"Id", p.Id},
{"Slot", p.Slot},
{"Count", p.Count},
{"Modifiers", p.Modifiers},
};
}
}
+19
View File
@@ -0,0 +1,19 @@
#include <cstdint>
#include <GWCA/GameEntities/Map.h>
#include <json.hpp>
#include <payloads/Build.h>
#include <payloads/Attribute.h>
using json = nlohmann::json;
namespace Daybreak {
void to_json(json& j, const Build& p) {
j = json
{
{"Primary", p.Primary},
{"Secondary", p.Secondary},
{"Attributes", p.Attributes},
{"Skills", p.Skills}
};
}
}
@@ -0,0 +1,22 @@
#include <cstdint>
#include <GWCA/GameEntities/Map.h>
#include <json.hpp>
#include <payloads/MainPlayer.h>
#include <payloads/MapIcon.h>
#include <payloads/GamePayload.h>
using json = nlohmann::json;
namespace Daybreak {
void to_json(json& j, const GamePayload& p) {
j = json
{
{"MainPlayer", p.MainPlayer},
{"Party", p.Party},
{"WorldPlayers", p.WorldPlayers},
{"LivingEntities", p.LivingEntities},
{"MapIcons", p.MapIcons},
{"TargetId", p.TargetId},
};
}
}
@@ -0,0 +1,14 @@
#include <cstdint>
#include <json.hpp>
#include <payloads/GameStatePayload.h>
using json = nlohmann::json;
namespace Daybreak {
void to_json(json& j, const GameStatePayload& p) {
j = json
{
{"States", p.States},
};
}
}
@@ -0,0 +1,25 @@
#include <cstdint>
#include <GWCA/GameEntities/Map.h>
#include <json.hpp>
#include <payloads/Bag.h>
#include <payloads/InventoryPayload.h>
using json = nlohmann::json;
namespace Daybreak {
void to_json(json& j, const InventoryPayload& p) {
j = json
{
{"GoldInStorage", p.GoldInStorage},
{"GoldOnCharacter", p.GoldOnCharacter},
{"Backpack", p.Backpack},
{"BeltPouch", p.BeltPouch},
{"Bags", p.Bags},
{"EquipmentPack", p.EquipmentPack},
{"MaterialStorage", p.MaterialStorage},
{"UnclaimedItems", p.UnclaimedItems},
{"StoragePanes", p.StoragePanes},
{"EquippedItems", p.EquippedItems},
};
}
}
@@ -0,0 +1,26 @@
#include <cstdint>
#include <GWCA/GameEntities/Map.h>
#include <json.hpp>
#include <payloads/LivingEntity.h>
using json = nlohmann::json;
namespace Daybreak {
void to_json(json& j, const LivingEntity& p) {
j = json
{
{"Id", p.Id},
{"Timer", p.Timer},
{"PosX", p.PosX},
{"PosY", p.PosY},
{"NpcDefinition", p.NpcDefinition},
{"PrimaryProfessionId", p.PrimaryProfessionId},
{"SecondaryProfessionId", p.SecondaryProfessionId},
{"Level", p.Level},
{"EntityState", p.EntityState},
{"EntityAllegiance", p.EntityAllegiance},
{"Health", p.Health},
{"Energy", p.Energy}
};
}
}
@@ -0,0 +1,16 @@
#include <cstdint>
#include <GWCA/GameEntities/Map.h>
#include <json.hpp>
#include <payloads/LoginPayload.h>
using json = nlohmann::json;
namespace Daybreak {
void to_json(json& j, const LoginPayload& p) {
j = json
{
{"Email", p.Email},
{"PlayerName", p.PlayerName},
};
}
}
@@ -0,0 +1,23 @@
#include <cstdint>
#include <GWCA/GameEntities/Map.h>
#include <json.hpp>
#include <payloads/WorldPlayer.h>
#include <payloads/QuestMetadata.h>
#include <payloads/MainPlayer.h>
using json = nlohmann::json;
namespace Daybreak {
void to_json(json& j, const MainPlayer& p) {
to_json(j, (WorldPlayer)p);
j["CurrentQuest"] = p.CurrentQuest;
j["QuestLog"] = p.QuestLog;
j["HardModeUnlocked"] = p.HardModeUnlocked;
j["Experience"] = p.Experience;
j["Morale"] = p.Morale;
j["CurrentHp"] = p.CurrentHp;
j["MaxHp"] = p.MaxHp;
j["CurrentEnergy"] = p.CurrentEnergy;
j["MaxEnergy"] = p.MaxEnergy;
}
}
+18
View File
@@ -0,0 +1,18 @@
#include <cstdint>
#include <GWCA/GameEntities/Map.h>
#include <json.hpp>
#include <payloads/MapIcon.h>
using json = nlohmann::json;
namespace Daybreak {
void to_json(json& j, const MapIcon& p) {
j = json
{
{"Id", p.Id},
{"PosX", p.PosX},
{"PosY", p.PosY},
{"Affiliation", p.Affiliation},
};
}
}
@@ -0,0 +1,22 @@
#include <cstdint>
#include <GWCA/GameEntities/Map.h>
#include <json.hpp>
#include <payloads/MapPayload.h>
using json = nlohmann::json;
namespace Daybreak {
void to_json(json& j, const MapPayload& p) {
j = json
{
{"IsLoaded", p.IsLoaded},
{"Id", p.Id},
{"InstanceType", p.InstanceType},
{"Timer", p.Timer},
{"Campaign", p.Campaign},
{"Continent", p.Continent},
{"Region", p.Region},
{"Type", p.Type},
};
}
}
@@ -0,0 +1,15 @@
#include <cstdint>
#include <json.hpp>
#include <payloads/NamePayload.h>
using json = nlohmann::json;
namespace Daybreak {
void to_json(json& j, const NamePayload& p) {
j = json
{
{"Id", p.Id},
{"Name", p.Name}
};
}
}
@@ -0,0 +1,15 @@
#include <cstdint>
#include <GWCA/GameEntities/Map.h>
#include <json.hpp>
#include <payloads/PathingMetadataPayload.h>
using json = nlohmann::json;
namespace Daybreak {
void to_json(json& j, const PathingMetadataPayload& p) {
j = json
{
{"TrapezoidCount", p.TrapezoidCount},
};
}
}
@@ -0,0 +1,17 @@
#include <cstdint>
#include <GWCA/GameEntities/Map.h>
#include <payloads/PathingTrapezoid.h>
#include <json.hpp>
#include <payloads/PathingPayload.h>
using json = nlohmann::json;
namespace Daybreak {
void to_json(json& j, const PathingPayload& p) {
j = json
{
{"Trapezoids", p.Trapezoids},
{"AdjacencyList", p.AdjacencyList}
};
}
}
@@ -0,0 +1,22 @@
#include <cstdint>
#include <GWCA/GameEntities/Map.h>
#include <json.hpp>
#include <payloads/PathingTrapezoid.h>
using json = nlohmann::json;
namespace Daybreak {
void to_json(json& j, const PathingTrapezoid& p) {
j = json
{
{"Id", p.Id},
{"PathingMapId", p.PathingMapId},
{"XTL", p.XTL},
{"XTR", p.XTR},
{"XBL", p.XBL},
{"XBR", p.XBR},
{"YT", p.YT},
{"YB", p.YB},
};
}
}
+17
View File
@@ -0,0 +1,17 @@
#include <cstdint>
#include <GWCA/GameEntities/Map.h>
#include <json.hpp>
#include <payloads/LivingEntity.h>
#include <payloads/Build.h>
#include <payloads/Player.h>
using json = nlohmann::json;
namespace Daybreak {
void to_json(json& j, const Player& p) {
to_json(j, (LivingEntity)p);
j["UnlockedProfession"] = p.UnlockedProfession;
j["NpcDefinition"] = p.NpcDefinition;
j["Build"] = p.Build;
}
}
@@ -0,0 +1,15 @@
#include <cstdint>
#include <json.hpp>
#include <payloads/PreGamePayload.h>
using json = nlohmann::json;
namespace Daybreak {
void to_json(json& j, const PreGamePayload& p) {
j = json
{
{"ChosenCharacterIndex", p.ChosenCharacterIndex},
{"Characters", p.Characters},
};
}
}

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