Compare commits

..
174 Commits
Author SHA1 Message Date
amacocian fe0a77d89d Fix automatic screen placer (Closes #708) (#714) 2024-05-06 00:27:48 +03:00
amacocian dbfd555f0d Improve detection of Guild Wars launching successfully (Closes #712) (#713) 2024-05-06 00:27:48 +03:00
amacocian 85d4ac3a29 Remove price checker (now incl. in Toolbox) (Closes #707) (#711) 2024-05-06 00:27:48 +03:00
amacocian dcb983d3de Update GWCA (#710) 2024-05-06 00:27:48 +03:00
amacocian ba1e4348ad Release 0.9.9.40 (#709) 2024-05-06 00:27:48 +03:00
amacocian 04bc7cffc6 Update GWCA (Closes #696) (#705) 2024-05-01 12:35:14 +03:00
amacocian 01b74a936b Rewrite GWCA module for better maintainability (#702)
* Use game thread enqueue method

* Remove manual memory handling

* Use game thread enqueue method

* Remove manual memory handling

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

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

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

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

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

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

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

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

* Event calendar view

* Update GWCA (#626)

* Publish changelog (#627)

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

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

* Option to disable dynamic backgrounds

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

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

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

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

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

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

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

* Minimap transparency
Closes #594

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

* Save extracted minimap window position (#591)

Closes #590

* Add ability to pin minimap to screen
Closes #585

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

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

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

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

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

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

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

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

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

* Copy buttons for build templates (#580)

* Extract minimap functionality (#581)

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

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

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

* Export team build from focus view (#573)

Closes #573

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

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

* Small buildtemplate binding fixes
Setup TeamBuildTemplateView

* Setup button to create team build

* Fix launch button (#566)

Closes #563

* Team build improvements (#568)

Closes #564

* Closes #562 (#569)

Closes #561

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

* Move injection to injector executable (#554)

* Fix logview missing history (#556)

Closes #526

* Detect unresponsive Guild Wars instance (#557)

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

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

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

* Fix dragging

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

* Increment version

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

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

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

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

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

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

* Setup ublock origin

* Release 0.9.9.7 branch

* Automatically backup settings
Closes #539

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

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

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

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

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

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

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

This reverts commit 9dbe4c5eaf.

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

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

* Change release procedure

* Fix gh release

* Fix release tag

* Change release structure to support folders

* Revert zip file changes to make them backwards compatible

* Change path

* Make launcher not contain the entire dependencies

* Add downtime after API rate limit

* Add rate limit checking before create release

* Enumerate through rates

* Adjust rate limit call

* Change to create release as draft

* Add update logic based on azure blobs

* Fix publish

* Create zip

* Disable CD pipeline for prs

* Increment version

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

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

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

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

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

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

Bumps Microsoft.Web.WebView2 from 1.0.2088.41 to 1.0.2151.40.

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

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

* Fix version

---------

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

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

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

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

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

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

* Complete Daybreak.GWCA implementation
Fix metrics view
Upgrade dependencies

* Update version

* Add solution dir property

* Another try

* Fix version check

* Fix codeql pipeline

* Codeql fixes

* Fetch submodules

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

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

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

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

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

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

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

* Increment version

---------

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

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

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

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

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

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

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

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

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

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

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

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

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-23 01:21:42 +02:00
amacocian dc0f833291 Re-create dependabot.yaml 2023-09-23 01:20:22 +02:00
amacocian e598237916 Remove dependabot.yaml 2023-09-23 01:19:56 +02:00
amacocianandGitHub 6b96d3d9e9 Inject toolbox dll into GuildWars (#389)
Closes #384
2023-09-22 23:11:36 +00:00
amacocianandGitHub 1dbb610846 Code cleanup (#387)
Closes #382
2023-09-22 16:10:07 +00:00
amacocianandGitHub 5c649b0c15 Integrate with uMod dll (#383) 2023-09-22 15:35:05 +00:00
amacocianandGitHub 527ab041d9 Fixes for the Background provider (#377)
Closes #376
2023-09-19 16:21:23 +00:00
amacocianandGitHub ff94e90259 Toggle background effects (#375) 2023-09-19 08:20:52 +00:00
amacocianandGitHub 51efbcce1e Update README.md (#374)
Signed-off-by: Macocian Alexandru Victor <amacocian@yahoo.com>
2023-09-19 09:28:37 +02:00
amacocianandGitHub 87b2345105 Daybreak Splash Screen (#373)
Closes #369
2023-09-16 12:57:07 +00:00
amacocianandGitHub 5022d33ca9 Ask for restart only when detecting change in plugins (#372)
Closes #371
2023-09-15 23:21:01 +00:00
amacocianandGitHub 141f949a63 Plugin support (#370)
Adds a plugin management view
Implements a basic plugin as an example
Closes #361
2023-09-15 19:22:52 +00:00
amacocianandGitHub 3913c71fd8 Release v107 (#368)
Handle browser component missing in FocusView
Fix credit text when failing to load image
Closes #298
Closes #366
2023-09-12 13:57:12 +00:00
amacocianandGitHub 5706652c40 Pathing drawing fix (#365)
Closes #364
2023-09-11 15:08:52 +00:00
amacocianandGitHub 768b6b20f5 Pathfinding improvements (#360)
Use optimization passes to improve final paths
2023-09-11 14:04:09 +00:00
658 changed files with 63063 additions and 6259 deletions
+39 -11
View File
@@ -20,7 +20,7 @@ jobs:
strategy:
matrix:
targetplatform: [x64]
targetplatform: [x86]
runs-on: windows-latest
@@ -33,7 +33,7 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0
@@ -46,16 +46,25 @@ jobs:
run: |
$changeLog = git log --no-merges --pretty="%h - %s (%an)<br />" ${{ env.LatestReleaseTag }}..HEAD
echo "::set-env name=Changelog::$changeLog"
mkdir Publish
echo $changeLog > .\Publish\changelog.txt
env:
LatestReleaseTag: ${{steps.getLatestTag.outputs.tag}}
- name: Install .NET Core
uses: actions/setup-dotnet@v3
uses: actions/setup-dotnet@v4
with:
dotnet-version: '7.x'
dotnet-version: '8.x'
- name: Setup MSBuild.exe
uses: microsoft/setup-msbuild@v1.3.1
uses: microsoft/setup-msbuild@v2.0.0
- 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: |
@@ -63,12 +72,12 @@ jobs:
dotnet user-secrets --project Daybreak\Daybreak.csproj set AadTenantId "${{ secrets.AadTenantId }}"
- name: Restore project
run: msbuild $env:Solution_Path /t:Restore /p:Configuration=$env:Configuration /p:RuntimeIdentifier=$env:RuntimeIdentifier
run: msbuild $env:Solution_Path /t:Restore /p:Configuration=$env:Configuration /p:RuntimeIdentifier=$env:RuntimeIdentifier --property:SolutionDir=$GITHUB_WORKSPACE
env:
RuntimeIdentifier: win-${{ matrix.targetplatform }}
- name: Build Daybreak project
run: dotnet build Daybreak -c $env:Configuration
run: dotnet build Daybreak -c $env:Configuration --property:SolutionDir=$env:GITHUB_WORKSPACE
- name: Set version variable
run: |
@@ -76,12 +85,17 @@ jobs:
echo "::set-env name=Version::$version"
- name: Create publish launcher files
run: dotnet publish .\Daybreak\Daybreak.csproj -c $env:Configuration -r $env:RuntimeIdentifier -p:PublishReadyToRun=true -p:PublishSingleFile=true --self-contained true -o .\Publish
run: dotnet publish .\Daybreak\Daybreak.csproj -c $env:Configuration -r $env:RuntimeIdentifier --property:SolutionDir=$env:GITHUB_WORKSPACE -p:PublishReadyToRun=true -p:PublishSingleFile=false --self-contained true -o .\Publish
env:
RuntimeIdentifier: win-${{ matrix.targetplatform }}
- name: Create publish installer files
run: dotnet publish .\Daybreak.Installer\Daybreak.Installer.csproj -c $env:Configuration -r $env:RuntimeIdentifier -p:PublishReadyToRun=true -p:PublishSingleFile=true --self-contained true -o .\Publish
run: dotnet publish .\Daybreak.Installer\Daybreak.Installer.csproj -c $env:Configuration -r $env:RuntimeIdentifier --property:SolutionDir=$env:GITHUB_WORKSPACE -p:PublishReadyToRun=true -p:PublishSingleFile=true --self-contained true -o .\Publish
env:
RuntimeIdentifier: win-${{ matrix.targetplatform }}
- name: Create publish extractor files
run: dotnet publish .\Daybreak.7ZipExtractor\Daybreak.7ZipExtractor.csproj -c $env:Configuration -r $env:RuntimeIdentifier --property:SolutionDir=$env:GITHUB_WORKSPACE -p:PublishReadyToRun=true -p:PublishSingleFile=false --self-contained true -o .\Publish
env:
RuntimeIdentifier: win-${{ matrix.targetplatform }}
@@ -91,8 +105,14 @@ jobs:
.\Scripts\BuildRelease.ps1 -version $env:Version
shell: pwsh
- name: Publish release
uses: Xotl/cool-github-releases@v1.1.8
- name: Publish blob files
run: |
Write-Host $env
.\Scripts\PushFilesToBlobStorage.ps1 -version $env:Version -sourcePath .\Publish\ -connectionString "${{ secrets.BLOBSTORAGE_CONNECTIONSTRING }}"
shell: pwsh
- name: Create release draft
uses: Xotl/cool-github-releases@v1.1.10
with:
mode: update
tag_name: v${{ env.Version }}
@@ -101,6 +121,14 @@ jobs:
github_token: ${{ env.GITHUB_TOKEN }}
replace_assets: true
body_mrkdwn: ${{ env.Changelog }}
isDraft: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Publish release
run: |
gh release edit v${{ env.Version }} --draft=false
shell: powershell
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+15 -8
View File
@@ -19,7 +19,7 @@ jobs:
strategy:
matrix:
targetplatform: [x64]
targetplatform: [x86]
runs-on: windows-latest
@@ -31,23 +31,30 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install .NET Core
uses: actions/setup-dotnet@v3
uses: actions/setup-dotnet@v4
with:
dotnet-version: '7.x'
dotnet-version: '8.x'
- name: Setup MSBuild.exe
uses: microsoft/setup-msbuild@v1.3.1
uses: microsoft/setup-msbuild@v2.0.0
- 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
run: dotnet test $env:Test_Project_Path --property:SolutionDir=$env:GITHUB_WORKSPACE -p:ParallelizeTestCollections=false
- name: Restore the Wpf application to populate the obj folder
run: msbuild $env:Solution_Path /t:Restore /p:Configuration=$env:Configuration /p:RuntimeIdentifier=$env:RuntimeIdentifier
run: msbuild $env:Solution_Path /t:Restore /p:Configuration=$env:Configuration /p:RuntimeIdentifier=$env:RuntimeIdentifier --property:SolutionDir=$env:GITHUB_WORKSPACE
env:
Configuration: Debug
RuntimeIdentifier: win-${{ matrix.targetplatform }}
+24 -8
View File
@@ -36,13 +36,26 @@ jobs:
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
env:
Configuration: Release
Solution_Path: Daybreak.sln
Test_Project_Path: Daybreak.Tests\Daybreak.Tests.csproj
Wpf_Project_Path: Daybreak\Daybreak.csproj
Actions_Allow_Unsecure_Commands: true
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Fetch submodules
run: |
git submodule update --init --recursive
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@@ -57,12 +70,12 @@ jobs:
# If this step fails, then you should remove it and run the build manually (see below)
- name: Install .NET Core
uses: actions/setup-dotnet@v3
uses: actions/setup-dotnet@v4
with:
dotnet-version: '7.x'
dotnet-version: '8.x'
- name: Autobuild
uses: github/codeql-action/autobuild@v2
#- name: Autobuild
# uses: github/codeql-action/autobuild@v2
# ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
@@ -74,5 +87,8 @@ jobs:
# echo "Run, Build Application using script"
# ./location_of_script_within_repo/buildscript.sh
- name: Build Daybreak project
run: dotnet build Daybreak -c $env:Configuration --property:SolutionDir=$env:GITHUB_WORKSPACE
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
uses: github/codeql-action/analyze@v3
+16 -4
View File
@@ -14,7 +14,7 @@ jobs:
strategy:
matrix:
targetplatform: [x64]
targetplatform: [x86]
runs-on: windows-latest
@@ -25,16 +25,28 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install .NET Core
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.x'
- 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
run: dotnet build Daybreak -c $env:Configuration --property:SolutionDir=$env:GITHUB_WORKSPACE
- name: Set version variable
run: |
+4 -1
View File
@@ -28,6 +28,7 @@ x86/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
build/
[Bb]in/
[Oo]bj/
[Oo]ut/
@@ -361,4 +362,6 @@ MigrationBackup/
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
FodyWeavers.xsd
.idea
+3
View File
@@ -0,0 +1,3 @@
[submodule "GWCA"]
path = GWCA
url = https://github.com/gwdevhub/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>net8.0</TargetFramework>
<RootNamespace>Daybreak._7ZipExtractor</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="SharpCompress" Version="0.37.2" />
</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;
+52
View File
@@ -0,0 +1,52 @@
# CMakeList.txt : CMake project for Daybreak.GWCA, include source and define
# project specific logic here.
#
project(Daybreak.GWCA VERSION 1.0.0)
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(VERSION_MAJOR 0)
set(VERSION_MINOR 9)
set(VERSION_PATCH 9)
set(VERSION_TWEAK 40)
set(VERSION_RC "${CMAKE_CURRENT_BINARY_DIR}/version.rc")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/version.rc.in" "${VERSION_RC}" @ONLY)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/bin")
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
set(CMAKE_INSTALL_PREFIX ${PROJECT_SOURCE_DIR}/bin/install)
add_compile_options(/MP /permissive-)
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})
source_group("Generated Files" FILES ${VERSION_RC})
target_sources(Daybreak.GWCA PRIVATE ${SOURCES} ${VERSION_RC})
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>
NOMINMAX
)
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);
}
}
+70
View File
@@ -0,0 +1,70 @@
#pragma once
#include <httplib.h>
#include <GWCA/Managers/GameThreadMgr.h>
#include <thread>
#include <json.hpp>
#include <semaphore>
#include <future>
#include <memory>
#include <string>
#include <optional>
using nlohmann::json;
namespace Daybreak {
template <typename TPayload, typename TContext>
class DaybreakModule {
protected:
std::future<std::optional<TPayload>> EnqueueWithReturn(const TContext context) {
std::shared_ptr<std::promise<std::optional<TPayload>>> promise = std::make_shared<std::promise<std::optional<TPayload>>>();
std::future<std::optional<TPayload>> ret = promise->get_future();
GW::GameThread::Enqueue([this, context, promise]() {
try {
const std::optional<TPayload> result = this->GetPayload(context);
promise->set_value(result);
}
catch (...) {
promise->set_exception(std::current_exception());
}
});
return ret;
}
virtual std::optional<TContext> GetContext(const httplib::Request& req, httplib::Response& res) = 0;
virtual bool CanReturn(const httplib::Request& req, httplib::Response& res, const TPayload& payload) {
return true;
}
virtual std::tuple<std::string, std::string> ReturnPayload(TPayload payload) {
return std::make_tuple(static_cast<json>(payload).dump(), "application/json");
}
virtual void OnNoValue(httplib::Response& res) {
res.status = 500;
res.body = "No payload";
}
virtual std::optional<TPayload> GetPayload(const TContext context) = 0;
public:
virtual std::string ApiUri() = 0;
void HandleApiCall(const httplib::Request& req, httplib::Response& res) {
const std::optional<TContext> context = this->GetContext(req, res);
if (!context.has_value()) {
return;
}
std::future<std::optional<TPayload>> future = this->EnqueueWithReturn(context.value());
std::optional<TPayload> payload = future.get();
if (!payload.has_value()) {
this->OnNoValue(res);
return;
}
while (!this->CanReturn(req, res, payload.value())) {
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
std::tuple<std::string, std::string> contentResponse = this->ReturnPayload(payload.value());
res.status = 200;
res.set_content(std::get<0>(contentResponse), std::get<1>(contentResponse));
}
};
}
+18
View File
@@ -0,0 +1,18 @@
#pragma once
#include "httplib.h"
#include <DaybreakModule.h>
#include <payloads/NamePayload.h>
namespace Daybreak::Modules {
class EntityNameModule : public DaybreakModule<NamePayload, uint32_t> {
public:
std::string ApiUri() override;
protected:
std::optional<uint32_t> GetContext(const httplib::Request& req, httplib::Response& res) override;
std::optional<NamePayload> GetPayload(uint32_t context) override;
bool CanReturn(const httplib::Request& req, httplib::Response& res, const NamePayload& payload) override;
std::tuple<std::string, std::string> ReturnPayload(NamePayload payload) override;
private:
std::wstring name;
};
}
+14
View File
@@ -0,0 +1,14 @@
#pragma once
#include "httplib.h"
#include <DaybreakModule.h>
#include <payloads/GamePayload.h>
namespace Daybreak::Modules {
class GameModule : public DaybreakModule<GamePayload, uint32_t> {
public:
std::string ApiUri() override;
protected:
std::optional<uint32_t> GetContext(const httplib::Request& req, httplib::Response& res) override;
std::optional<GamePayload> GetPayload(const uint32_t) override;
};
}
+14
View File
@@ -0,0 +1,14 @@
#pragma once
#include "httplib.h"
#include <DaybreakModule.h>
#include <payloads/GameStatePayload.h>
namespace Daybreak::Modules {
class GameStateModule : public DaybreakModule<GameStatePayload, uint32_t> {
public:
std::string ApiUri() override;
protected:
std::optional<uint32_t> GetContext(const httplib::Request& req, httplib::Response& res) override;
std::optional<GameStatePayload> GetPayload(const uint32_t) override;
};
}
+6
View File
@@ -0,0 +1,6 @@
#pragma once
#include "httplib.h"
namespace http {
void ConsoleLogger(const httplib::Request req, httplib::Response res);
}
+14
View File
@@ -0,0 +1,14 @@
#pragma once
#include "httplib.h"
#include <DaybreakModule.h>
#include <payloads/InventoryPayload.h>
namespace Daybreak::Modules {
class InventoryModule : public DaybreakModule<InventoryPayload, uint32_t> {
protected:
std::optional<uint32_t> GetContext(const httplib::Request& req, httplib::Response& res) override;
std::optional<InventoryPayload> GetPayload(const uint32_t) override;
public:
std::string ApiUri() override;
};
}
+19
View File
@@ -0,0 +1,19 @@
#pragma once
#include "httplib.h"
#include <DaybreakModule.h>
#include <payloads/NamePayload.h>
#include <GWCA/GameEntities/Item.h>
namespace Daybreak::Modules {
class ItemNameModule : public DaybreakModule<NamePayload, GW::Item*> {
public:
std::string ApiUri() override;
protected:
std::optional<GW::Item*> GetContext(const httplib::Request& req, httplib::Response& res) override;
std::optional<NamePayload> GetPayload(GW::Item* context) override;
bool CanReturn(const httplib::Request& req, httplib::Response& res, const NamePayload& payload) override;
std::tuple<std::string, std::string> ReturnPayload(NamePayload payload) override;
private:
std::wstring name;
};
}
+14
View File
@@ -0,0 +1,14 @@
#pragma once
#include "httplib.h"
#include <DaybreakModule.h>
#include <payloads/LoginPayload.h>
namespace Daybreak::Modules {
class LoginModule : public DaybreakModule<LoginPayload, uint32_t>{
public:
std::string ApiUri() override;
protected:
std::optional<uint32_t> GetContext(const httplib::Request& req, httplib::Response& res) override;
std::optional<LoginPayload> GetPayload(const uint32_t) override;
};
}
+14
View File
@@ -0,0 +1,14 @@
#pragma once
#include "httplib.h"
#include <DaybreakModule.h>
#include <payloads/MainPlayer.h>
namespace Daybreak::Modules {
class MainPlayerModule : public DaybreakModule<MainPlayer, uint32_t> {
public:
std::string ApiUri() override;
protected:
std::optional<uint32_t> GetContext(const httplib::Request& req, httplib::Response& res) override;
std::optional<MainPlayer> GetPayload(const uint32_t) override;
};
}
+14
View File
@@ -0,0 +1,14 @@
#pragma once
#include "httplib.h"
#include <DaybreakModule.h>
#include <payloads/MapPayload.h>
namespace Daybreak::Modules {
class MapModule : public DaybreakModule<MapPayload, uint32_t> {
public:
std::string ApiUri() override;
protected:
std::optional<uint32_t> GetContext(const httplib::Request& req, httplib::Response& res) override;
std::optional<MapPayload> GetPayload(const uint32_t) override;
};
}
@@ -0,0 +1,14 @@
#pragma once
#include "httplib.h"
#include <DaybreakModule.h>
#include <payloads/PathingMetadataPayload.h>
namespace Daybreak::Modules {
class PathingMetadataModule : public DaybreakModule<PathingMetadataPayload, uint32_t> {
public:
std::string ApiUri() override;
protected:
std::optional<uint32_t> GetContext(const httplib::Request& req, httplib::Response& res) override;
std::optional<PathingMetadataPayload> GetPayload(const uint32_t) override;
};
}
+14
View File
@@ -0,0 +1,14 @@
#pragma once
#include "httplib.h"
#include <DaybreakModule.h>
#include <payloads/PathingPayload.h>
namespace Daybreak::Modules {
class PathingModule : public DaybreakModule<PathingPayload, uint32_t> {
public:
std::string ApiUri() override;
protected:
std::optional<uint32_t> GetContext(const httplib::Request& req, httplib::Response& res) override;
std::optional<PathingPayload> GetPayload(const uint32_t) override;
};
}
+14
View File
@@ -0,0 +1,14 @@
#pragma once
#include "httplib.h"
#include <DaybreakModule.h>
#include <payloads/PreGamePayload.h>
namespace Daybreak::Modules {
class PreGameModule : public DaybreakModule<PreGamePayload, uint32_t> {
public:
std::string ApiUri() override;
protected:
std::optional<uint32_t> GetContext(const httplib::Request& req, httplib::Response& res) override;
std::optional<PreGamePayload> GetPayload(const uint32_t) override;
};
}
+8
View File
@@ -0,0 +1,8 @@
#pragma once
#include "httplib.h"
namespace http {
namespace modules {
void HandleProcessId(const httplib::Request&, httplib::Response& res);
}
}
+13
View File
@@ -0,0 +1,13 @@
#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);
void Post(const std::string& pattern, httplib::Server::Handler handler);
}
}
+14
View File
@@ -0,0 +1,14 @@
#pragma once
#include "httplib.h"
#include <DaybreakModule.h>
#include <payloads/SessionPayload.h>
namespace Daybreak::Modules {
class SessionModule : public DaybreakModule<SessionPayload, uint32_t> {
public:
std::string ApiUri() override;
protected:
std::optional<uint32_t> GetContext(const httplib::Request& req, httplib::Response& res) override;
std::optional<SessionPayload> GetPayload(const uint32_t) override;
};
}
+21
View File
@@ -0,0 +1,21 @@
#pragma once
#include "httplib.h"
#include <DaybreakModule.h>
#include <TitleInfoModule.h>
#include <payloads/TitleInfoPayload.h>
#include <tuple>
#include <string>
namespace Daybreak::Modules {
class TitleInfoModule : public DaybreakModule<TitleInfoPayload, uint32_t> {
public:
std::string ApiUri() override;
protected:
std::optional<TitleInfoPayload> GetPayload(const uint32_t context) override;
std::tuple<std::string, std::string> ReturnPayload(TitleInfoPayload payload) override;
bool CanReturn(const httplib::Request& req, httplib::Response& res, const TitleInfoPayload& payload) override;
std::optional<uint32_t> GetContext(const httplib::Request& req, httplib::Response& res) override;
private:
std::wstring name;
};
}
+14
View File
@@ -0,0 +1,14 @@
#pragma once
#include "httplib.h"
#include <DaybreakModule.h>
#include <payloads/UserPayload.h>
namespace Daybreak::Modules {
class UserModule : public DaybreakModule<UserPayload, uint32_t> {
public:
std::string ApiUri() override;
protected:
std::optional<uint32_t> GetContext(const httplib::Request& req, httplib::Response& res) override;
std::optional<UserPayload> GetPayload(const uint32_t) override;
};
}
+8
View File
@@ -0,0 +1,8 @@
#pragma once
#include <string>
namespace Daybreak::Utils {
std::string WStringToString(const std::wstring& wstr);
std::wstring StringToWString(const std::string& str);
bool StringToInt(const std::string& str, int& outValue);
}
+15
View File
@@ -0,0 +1,15 @@
#pragma once
#include "httplib.h"
#include <DaybreakModule.h>
#include <string>
namespace Daybreak::Modules {
class WhisperModule : public DaybreakModule<bool, std::wstring> {
public:
std::string ApiUri() override;
protected:
std::optional<std::wstring> GetContext(const httplib::Request& req, httplib::Response& res) override;
std::optional<bool> GetPayload(const std::wstring message) override;
std::tuple<std::string, std::string> ReturnPayload(bool) override;
};
}
+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);
}
+14
View File
@@ -0,0 +1,14 @@
#pragma once
#include <cstdint>
#include <json.hpp>
using json = nlohmann::json;
namespace Daybreak {
struct Camera {
float Yaw;
float Pitch;
};
void to_json(json& j, const Camera& 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,16 @@
#pragma once
#include <cstdint>
#include <json.hpp>
#include <payloads/StatePayload.h>
#include <payloads/Camera.h>
using json = nlohmann::json;
namespace Daybreak {
struct GameStatePayload {
Camera Camera;
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,26 @@
#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;
float RotationAngle;
};
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 = -1;
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,19 @@
#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;
float RotationAngle = 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,19 @@
#pragma once
#include <cstdint>
#include <json.hpp>
using json = nlohmann::json;
namespace Daybreak {
struct TitleInfoPayload {
uint32_t TitleId = 0;
uint32_t TitleTierId = 0;
uint32_t CurrentTier = 0;
uint32_t CurrentPoints = 0;
uint32_t PointsNeededNextRank = 0;
bool IsPercentageBased = false;
std::string TitleName = "";
};
void to_json(json& j, const TitleInfoPayload& 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");
}
}
}
+79
View File
@@ -0,0 +1,79 @@
#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 {
std::string EntityNameModule::ApiUri()
{
return "/entities/name";
}
std::optional<uint32_t> EntityNameModule::GetContext(const httplib::Request& req, httplib::Response& res)
{
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 std::optional<uint32_t>();
}
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 std::optional<uint32_t>();
}
id = static_cast<uint32_t>(result);
}
return id;
}
std::optional<NamePayload> EntityNameModule::GetPayload(const uint32_t context)
{
NamePayload namePayload;
auto agent = GW::Agents::GetAgentByID(context);
if (!agent) {
return std::optional<NamePayload>();
}
auto agentLiving = agent->GetAsAgentLiving();
if (!agentLiving) {
return std::optional<NamePayload>();
}
if (!GW::Agents::AsyncGetAgentName(agentLiving, this->name)) {
return std::optional<NamePayload>();
}
namePayload.Id = context;
return namePayload;
}
bool EntityNameModule::CanReturn(const httplib::Request& req, httplib::Response& res, const NamePayload& payload) {
return !name.empty();
}
std::tuple<std::string, std::string> EntityNameModule::ReturnPayload(NamePayload payload) {
payload.Name = Daybreak::Utils::WStringToString(this->name);
return std::make_tuple(static_cast<json>(payload).dump(), "application/json");
}
}
+580
View File
@@ -0,0 +1,580 @@
#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 {
namespace GameModuleInternal {
std::list<QuestMetadata> GetQuestLog() {
std::list<QuestMetadata> questMetadatas;
const auto questLog = GW::QuestMgr::GetQuestLog();
if (!questLog) {
return questMetadatas;
}
for (const 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;
const auto worldContext = GW::GetWorldContext();
for (const auto& agent : worldContext->map_agents) {
entities.push_back(agent);
}
return entities;
}
std::list<GW::PartyAttribute> GetPartyAttributes() {
std::list<GW::PartyAttribute> attributes;
const auto worldContext = GW::GetWorldContext();
for (const auto& attribute : worldContext->attributes) {
attributes.push_back(attribute);
}
return attributes;
}
std::list<GW::ProfessionState> GetProfessions() {
std::list<GW::ProfessionState> professions;
const auto worldContext = GW::GetWorldContext();
for (const 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 (const 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;
const auto worldContext = GW::GetWorldContext();
for (const auto& title : worldContext->title_tiers) {
titles.push_back(title);
}
return titles;
}
std::list<GW::Title> GetTitles() {
std::list<GW::Title> titles;
const auto worldContext = GW::GetWorldContext();
for (const auto& title : worldContext->titles) {
titles.push_back(title);
}
return titles;
}
std::list<Temp::GWPlayer> GetPlayers() {
std::list<Temp::GWPlayer> players;
const auto worldContext = GW::GetWorldContext();
Temp::GWPlayer* tempPlayerArray = (Temp::GWPlayer*)worldContext->players.m_buffer;
if (!tempPlayerArray) {
return players;
}
for (auto i = 0U; 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;
const auto skillbars = GW::SkillbarMgr::GetSkillbarArray();
if (!skillbars) {
return skillbarMap;
}
for (const 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 (const 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;
entity.RotationAngle = agent.rotation_angle;
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++) {
const 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);
player.RotationAngle = agent->rotation_angle;
}
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);
const auto name = Daybreak::Utils::WStringToString(nameString);
player.Name = name;
if (titles.empty() ||
titleTiers.empty()) {
return;
}
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;
}
const 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;
}
}
}
std::string GameModule::ApiUri()
{
return "/game";
}
std::optional<uint32_t> GameModule::GetContext(const httplib::Request& req, httplib::Response& res)
{
return NULL;
}
std::optional<GamePayload> GameModule::GetPayload(uint32_t)
{
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 = GameModuleInternal::GetQuestLog();
auto skillbars = GameModuleInternal::GetSkillbars();
if (skillbars.empty()) {
return gamePayload;
}
auto agents = GameModuleInternal::GetLivingAgents();
if (agents.empty()) {
return gamePayload;
}
auto titles = GameModuleInternal::GetTitles();
auto titleTiers = GameModuleInternal::GetTitleTiers();
auto players = GameModuleInternal::GetPlayers();
if (players.empty()) {
return gamePayload;
}
auto attributes = GameModuleInternal::GetPartyAttributes();
if (attributes.empty()) {
return gamePayload;
}
auto professions = GameModuleInternal::GetProfessions();
if (professions.empty()) {
return gamePayload;
}
auto mapAgents = GameModuleInternal::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;
}
GameModuleInternal::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;
}
GameModuleInternal::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;
GameModuleInternal::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 = GameModuleInternal::GetLivingEntities(livingEntities);
gamePayload.LivingEntities = livingEntityList;
return gamePayload;
}
}
+83
View File
@@ -0,0 +1,83 @@
#include "pch.h"
#include "GameStateModule.h"
#include <GWCA/Managers/GameThreadMgr.h>
#include <GWCA/Managers/AgentMgr.h>
#include <GWCA/Managers/CameraMgr.h>
#include <GWCA/GameEntities/Agent.h>
#include <GWCA/GameEntities/Camera.h>
#include <GWCA/Managers/MapMgr.h>
#include <future>
#include <payloads/GameStatePayload.h>
#include <json.hpp>
#include <queue>
#include <algorithm>
namespace Daybreak::Modules {
namespace GameStateModuleInternal {
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 (const 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);
state.RotationAngle = agent.rotation_angle;
states.push_back(state);
}
return states;
}
}
std::optional<GameStatePayload> GameStateModule::GetPayload(uint32_t) {
GameStatePayload gamePayload;
if (!GW::Map::GetIsMapLoaded()) {
return gamePayload;
}
auto agents = GameStateModuleInternal::GetLivingAgents();
if (agents.empty()) {
return gamePayload;
}
auto states = GameStateModuleInternal::GetStates(agents);
gamePayload.States = states;
auto camera = GW::CameraMgr::GetCamera();
Daybreak::Camera cameraPayload{};
cameraPayload.Pitch = camera->pitch;
cameraPayload.Yaw = camera->yaw;
gamePayload.Camera = cameraPayload;
return gamePayload;
}
std::string GameStateModule::ApiUri() {
return "/game/state";
}
std::optional<uint32_t> GameStateModule::GetContext(const httplib::Request& req, httplib::Response& res) {
return 0;
}
}
+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;
}
}
+90
View File
@@ -0,0 +1,90 @@
#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 {
namespace InventoryModuleInternal {
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 = 0U; i < item->mod_struct_size; i++) {
bagContent.Modifiers.push_back((uint32_t)(modifier->mod));
modifier++;
}
retBag.Items.push_back(bagContent);
}
return retBag;
}
}
std::optional<InventoryPayload> InventoryModule::GetPayload(const uint32_t) {
InventoryPayload inventoryPayload;
if (!GW::Map::GetIsMapLoaded()) {
return inventoryPayload;
}
auto inventory = GW::GetItemContext()->inventory;
if (!inventory) {
return inventoryPayload;
}
inventoryPayload.GoldInStorage = GW::Items::GetGoldAmountInStorage();
inventoryPayload.GoldOnCharacter = GW::Items::GetGoldAmountOnCharacter();
inventoryPayload.Backpack = InventoryModuleInternal::GetBag(inventory->backpack);
inventoryPayload.BeltPouch = (InventoryModuleInternal::GetBag(inventory->belt_pouch));
inventoryPayload.Bags.push_back(InventoryModuleInternal::GetBag(inventory->bag1));
inventoryPayload.Bags.push_back(InventoryModuleInternal::GetBag(inventory->bag2));
inventoryPayload.EquipmentPack = (InventoryModuleInternal::GetBag(inventory->equipment_pack));
inventoryPayload.MaterialStorage = (InventoryModuleInternal::GetBag(inventory->material_storage));
inventoryPayload.UnclaimedItems = (InventoryModuleInternal::GetBag(inventory->unclaimed_items));
inventoryPayload.EquippedItems = (InventoryModuleInternal::GetBag(inventory->equipped_items));
inventoryPayload.StoragePanes.push_back(InventoryModuleInternal::GetBag(inventory->storage1));
inventoryPayload.StoragePanes.push_back(InventoryModuleInternal::GetBag(inventory->storage2));
inventoryPayload.StoragePanes.push_back(InventoryModuleInternal::GetBag(inventory->storage3));
inventoryPayload.StoragePanes.push_back(InventoryModuleInternal::GetBag(inventory->storage4));
inventoryPayload.StoragePanes.push_back(InventoryModuleInternal::GetBag(inventory->storage5));
inventoryPayload.StoragePanes.push_back(InventoryModuleInternal::GetBag(inventory->storage6));
inventoryPayload.StoragePanes.push_back(InventoryModuleInternal::GetBag(inventory->storage7));
inventoryPayload.StoragePanes.push_back(InventoryModuleInternal::GetBag(inventory->storage8));
inventoryPayload.StoragePanes.push_back(InventoryModuleInternal::GetBag(inventory->storage9));
inventoryPayload.StoragePanes.push_back(InventoryModuleInternal::GetBag(inventory->storage10));
inventoryPayload.StoragePanes.push_back(InventoryModuleInternal::GetBag(inventory->storage11));
inventoryPayload.StoragePanes.push_back(InventoryModuleInternal::GetBag(inventory->storage12));
inventoryPayload.StoragePanes.push_back(InventoryModuleInternal::GetBag(inventory->storage13));
inventoryPayload.StoragePanes.push_back(InventoryModuleInternal::GetBag(inventory->storage14));
return inventoryPayload;
}
std::optional<uint32_t> InventoryModule::GetContext(const httplib::Request& req, httplib::Response& res)
{
return 0;
}
std::string InventoryModule::ApiUri()
{
return "/inventory";
}
}
+115
View File
@@ -0,0 +1,115 @@
#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 {
namespace ItemNameModuleInternal {
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;
}
}
std::string ItemNameModule::ApiUri() {
return "/items/name";
}
std::optional<GW::Item*> ItemNameModule::GetContext(const httplib::Request& req, httplib::Response& res) {
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 std::optional<GW::Item*>();
}
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 std::optional<GW::Item*>();
}
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 std::optional<GW::Item*>();
}
else {
auto& modifiersStr = mod_it->second;
const auto tokens = ItemNameModuleInternal::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 std::optional<GW::Item*>();
}
modifiers.push_back(static_cast<uint32_t>(parsedModifier));
}
}
GW::ItemModifier parsedModifiers[64];
for (auto i = 0U; 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 std::optional<GW::Item*>();
}
return item;
}
std::optional<NamePayload> ItemNameModule::GetPayload(GW::Item* context) {
NamePayload payload;
if (!context) {
return std::optional<NamePayload>();
}
payload.Id = context->item_id;
GW::Items::AsyncGetItemName(context, this->name);
return payload;
}
bool ItemNameModule::CanReturn(const httplib::Request& req, httplib::Response& res, const NamePayload& payload) {
return !name.empty();
}
std::tuple<std::string, std::string> ItemNameModule::ReturnPayload(NamePayload payload) {
payload.Name = Daybreak::Utils::WStringToString(this->name);
return std::make_tuple(static_cast<json>(payload).dump(), "application/json");
}
}
+36
View File
@@ -0,0 +1,36 @@
#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 {
std::optional<LoginPayload> LoginModule::GetPayload(const uint32_t) {
const auto context = GW::GetCharContext();
LoginPayload loginPayload;
if (!context) {
return 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;
}
std::optional<uint32_t> LoginModule::GetContext(const httplib::Request& req, httplib::Response& res) {
return 0;
}
std::string LoginModule::ApiUri()
{
return "/login";
}
}
+481
View File
@@ -0,0 +1,481 @@
#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 {
namespace MainPlayerModuleInternal {
std::list<QuestMetadata> GetQuestLog() {
std::list<QuestMetadata> questMetadatas;
const 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;
const auto worldContext = GW::GetWorldContext();
if (!worldContext) {
return entities;
}
for (auto& agent : worldContext->map_agents) {
entities.push_back(agent);
}
return entities;
}
std::list<GW::PartyAttribute> GetPartyAttributes() {
std::list<GW::PartyAttribute> attributes;
const auto worldContext = GW::GetWorldContext();
if (!worldContext) {
return attributes;
}
for (auto& attribute : worldContext->attributes) {
attributes.push_back(attribute);
}
return attributes;
}
std::list<GW::ProfessionState> GetProfessions() {
std::list<GW::ProfessionState> professions;
const auto worldContext = GW::GetWorldContext();
if (!worldContext) {
return professions;
}
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 = 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;
const auto worldContext = GW::GetWorldContext();
if (!worldContext) {
return npcs;
}
for (auto& npc : worldContext->npcs) {
npcs.push_back(npc);
}
return npcs;
}
std::vector<GW::TitleTier> GetTitleTiers() {
std::vector<GW::TitleTier> titles;
const auto worldContext = GW::GetWorldContext();
if (!worldContext) {
return titles;
}
for (auto& title : worldContext->title_tiers) {
titles.push_back(title);
}
return titles;
}
std::list<GW::Title> GetTitles() {
std::list<GW::Title> titles;
const auto worldContext = GW::GetWorldContext();
if (!worldContext) {
return titles;
}
for (auto& title : worldContext->titles) {
titles.push_back(title);
}
return titles;
}
std::list<Temp::GWPlayer> GetPlayers() {
std::list<Temp::GWPlayer> players;
const auto worldContext = GW::GetWorldContext();
if (!worldContext) {
return players;
}
Temp::GWPlayer* tempPlayerArray = (Temp::GWPlayer*)worldContext->players.m_buffer;
if (!tempPlayerArray) {
return players;
}
for (auto i = 0U; 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);
player.RotationAngle = agent->rotation_angle;
}
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;
if (titles.empty() ||
titleTiers.empty()) {
return;
}
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;
}
}
}
std::optional<MainPlayer> MainPlayerModule::GetPayload(const uint32_t) {
MainPlayer mainPlayer;
if (!GW::Map::GetIsMapLoaded()) {
return mainPlayer;
}
auto worldContext = GW::GetWorldContext();
if (!worldContext) {
return mainPlayer;
}
auto activeQuestId = GW::QuestMgr::GetActiveQuestId();
auto questLog = MainPlayerModuleInternal::GetQuestLog();
auto skillbars = MainPlayerModuleInternal::GetSkillbars();
if (skillbars.empty()) {
return mainPlayer;
}
auto agents = MainPlayerModuleInternal::GetLivingAgents();
if (agents.empty()) {
return mainPlayer;
}
auto titles = MainPlayerModuleInternal::GetTitles();
auto titleTiers = MainPlayerModuleInternal::GetTitleTiers();
auto players = MainPlayerModuleInternal::GetPlayers();
if (players.empty()) {
return mainPlayer;
}
auto npcs = MainPlayerModuleInternal::GetNpcs();
if (npcs.empty()) {
return mainPlayer;
}
auto attributes = MainPlayerModuleInternal::GetPartyAttributes();
if (attributes.empty()) {
return mainPlayer;
}
auto professions = MainPlayerModuleInternal::GetProfessions();
if (professions.empty()) {
return mainPlayer;
}
auto mapAgents = MainPlayerModuleInternal::GetMapEntities();
if (mapAgents.empty()) {
return mainPlayer;
}
auto playerAgentId = GW::Agents::GetPlayerId();
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;
}
MainPlayerModuleInternal::PopulateMainPlayer(mainPlayer, (uint32_t)activeQuestId, questLog, titles, titleTiers, playerAgentId, mainGwPlayer, mainProfPtr, skillbars[playerAgentId], mainAttrPtr, mainAgentPtr);
return mainPlayer;
}
std::optional<uint32_t> MainPlayerModule::GetContext(const httplib::Request& req, httplib::Response& res)
{
return NULL;
}
std::string MainPlayerModule::ApiUri()
{
return "/game/mainplayer";
}
}
+48
View File
@@ -0,0 +1,48 @@
#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 {
std::optional<MapPayload> MapModule::GetPayload(const uint32_t) {
MapPayload mapPayload;
auto isLoaded = GW::Map::GetIsMapLoaded();
if (!isLoaded) {
return mapPayload;
}
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();
if (!mapInfo) {
return mapPayload;
}
mapPayload.Campaign = static_cast<uint32_t>(mapInfo->campaign);
mapPayload.Continent = static_cast<uint32_t>(mapInfo->continent);
mapPayload.Region = mapInfo->region;
mapPayload.InstanceType = (uint32_t)instanceType;
mapPayload.IsLoaded = isLoaded;
mapPayload.Timer = instanceTime;
mapPayload.Id = (uint32_t)mapId;
return mapPayload;
}
std::string MapModule::ApiUri()
{
return "/map";
}
std::optional<uint32_t> MapModule::GetContext(const httplib::Request& req, httplib::Response& res)
{
return NULL;
}
}
@@ -0,0 +1,43 @@
#include "pch.h"
#include "PathingMetadataModule.h"
#include <GWCA/Managers/GameThreadMgr.h>
#include <GWCA/Managers/MapMgr.h>
#include <GWCA/GameEntities/Pathing.h>
#include <future>
#include <payloads/PathingMetadataPayload.h>
#include <json.hpp>
#include <queue>
namespace Daybreak::Modules {
std::optional<PathingMetadataPayload> PathingMetadataModule::GetPayload(const uint32_t) {
PathingMetadataPayload pathingPayload;
pathingPayload.TrapezoidCount = 0;
if (!GW::Map::GetIsMapLoaded()) {
return pathingPayload;
}
auto pathingMap = GW::Map::GetPathingMap();
if (!pathingMap) {
return pathingPayload;
}
int count = 0;
for (auto i = 0U; i < pathingMap->size(); i++) {
auto gwPathingMap = pathingMap->at(i);
count += gwPathingMap.trapezoid_count;
}
pathingPayload.TrapezoidCount = count;
return pathingPayload;
}
std::string PathingMetadataModule::ApiUri()
{
return "/pathing/metadata";
}
std::optional<uint32_t> PathingMetadataModule::GetContext(const httplib::Request& req, httplib::Response& res)
{
return NULL;
}
}
+70
View File
@@ -0,0 +1,70 @@
#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 {
std::optional<PathingPayload> PathingModule::GetPayload(const uint32_t) {
PathingPayload pathingPayload;
pathingPayload.Trapezoids.clear();
pathingPayload.AdjacencyList.clear();
if (!GW::Map::GetIsMapLoaded()) {
return pathingPayload;
}
auto pathingMap = GW::Map::GetPathingMap();
if (!pathingMap) {
return pathingPayload;
}
std::list<PathingTrapezoid> trapezoids;
std::map<int, std::list<int>> adjacencyMap;
for (auto i = 0U; i < pathingMap->size(); i++) {
auto gwPathingMap = pathingMap->at(i);
for (auto j = 0U; 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;
}
std::string PathingModule::ApiUri()
{
return "/pathing";
}
std::optional<uint32_t> PathingModule::GetContext(const httplib::Request& req, httplib::Response& res)
{
return NULL;
}
}
+50
View File
@@ -0,0 +1,50 @@
#include "pch.h"
#include <PreGameModule.h>
#include <GWCA/Managers/GameThreadMgr.h>
#include <GWCA/Managers/MapMgr.h>
#include <GWCA/Context/PreGameContext.h>
#include <payloads/PreGamePayload.h>
#include <json.hpp>
namespace Daybreak::Modules {
std::optional<PreGamePayload> PreGameModule::GetPayload(const uint32_t) {
PreGamePayload preGamePayload;
if (GW::Map::GetIsMapLoaded())
{
preGamePayload.Characters.clear();
preGamePayload.ChosenCharacterIndex = 0;
return preGamePayload;
}
const auto context = GW::GetPreGameContext();
if (!context)
{
return preGamePayload;
}
for (const auto& loginChar : context->chars)
{
char charName[20];
int result = WideCharToMultiByte(CP_UTF8, 0, loginChar.character_name, -1, charName, sizeof(charName), NULL, NULL);
if (result == 0)
{
// handle error, use GetLastError() to get more info
}
preGamePayload.Characters.emplace_back(charName);
}
preGamePayload.ChosenCharacterIndex = context->index_1;
return preGamePayload;
}
std::string PreGameModule::ApiUri()
{
return "/pregame";
}
std::optional<uint32_t> PreGameModule::GetContext(const httplib::Request& req, httplib::Response& res)
{
return NULL;
}
}
+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");
}
}
}
+83
View File
@@ -0,0 +1,83 @@
#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 Post(const std::string& pattern, httplib::Server::Handler handler) {
server.Post(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.set_read_timeout(1, 0);
server.set_write_timeout(1, 0);
server.set_idle_interval(0, 100000);
server.listen("0.0.0.0", port);
return true;
}
return false;
}
void StopServer() {
server.stop();
}
}
}
+44
View File
@@ -0,0 +1,44 @@
#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 {
std::optional<SessionPayload> SessionModule::GetPayload(const uint32_t) {
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;
}
std::string SessionModule::ApiUri()
{
return "/session";
}
std::optional<uint32_t> SessionModule::GetContext(const httplib::Request& req, httplib::Response& res)
{
return NULL;
}
}
+87
View File
@@ -0,0 +1,87 @@
#include "pch.h"
#include "TitleInfoModule.h"
#include "payloads/TitleInfoPayload.h"
#include <DaybreakModule.h>
#include <Utils.h>
#include <GWCA/GameContainers/Array.h>
#include <GWCA/Managers/GameThreadMgr.h>
#include <GWCA/Managers/MapMgr.h>
#include <GWCA/Managers/PlayerMgr.h>
#include <GWCA/Constants/AgentIDs.h>
#include <GWCA/GameEntities/Title.h>
#include <GWCA/Context/WorldContext.h>
#include <GWCA/Constants/Constants.h>
#include <GWCA/Managers/UIMgr.h>
namespace Daybreak::Modules {
std::string TitleInfoModule::ApiUri()
{
return "/titles/info";
}
std::optional<TitleInfoPayload> TitleInfoModule::GetPayload(const uint32_t context) {
TitleInfoPayload payload;
if (!GW::Map::GetIsMapLoaded()) {
return std::optional<TitleInfoPayload>();
}
const auto title = GW::PlayerMgr::GetTitleTrack((GW::Constants::TitleID)context);
if (!title) {
return std::optional<TitleInfoPayload>();
}
if (title->current_points == 0 &&
title->current_title_tier_index == 0 &&
title->next_title_tier_index == 0 &&
title->max_title_rank == 0) {
return std::optional<TitleInfoPayload>();
}
const auto tierIndex = title->current_title_tier_index;
const auto worldContext = GW::GetWorldContext();
const auto tiers = &worldContext->title_tiers;
const auto tier = &tiers->at(tierIndex);
payload.TitleId = context;
payload.TitleTierId = tierIndex;
payload.CurrentPoints = title->current_points;
payload.PointsNeededNextRank = title->points_needed_next_rank;
payload.IsPercentageBased = title->is_percentage_based();
payload.CurrentTier = tier->tier_number;
GW::UI::AsyncDecodeStr(tier->tier_name_enc, &this->name);
return payload;
}
bool TitleInfoModule::CanReturn(const httplib::Request& req, httplib::Response& res, const TitleInfoPayload& payload) {
return !name.empty();
}
std::tuple<std::string, std::string> TitleInfoModule::ReturnPayload(TitleInfoPayload payload) {
payload.TitleName = Daybreak::Utils::WStringToString(name);
return std::make_tuple(static_cast<json>(payload).dump(), "application/json");
}
std::optional<uint32_t> TitleInfoModule::GetContext(const httplib::Request& req, httplib::Response& res) {
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 std::optional<uint32_t>();
}
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 std::optional<uint32_t>();
}
id = static_cast<uint32_t>(result);
}
return id;
}
}
+59
View File
@@ -0,0 +1,59 @@
#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 {
std::optional<UserPayload> UserModule::GetPayload(const uint32_t) {
UserPayload userPayload;
auto charContext = GW::GetCharContext();
auto worldContext = GW::GetWorldContext();
if (!charContext) {
return userPayload;
}
if (!worldContext) {
return userPayload;
}
char emailStr[64];
int result = WideCharToMultiByte(CP_UTF8, 0, charContext->player_email, -1, emailStr, sizeof(emailStr), NULL, NULL);
if (result == 0) {
// handle error, use GetLastError() to get more info
}
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;
}
std::string UserModule::ApiUri()
{
return "/user";
}
std::optional<uint32_t> UserModule::GetContext(const httplib::Request& req, httplib::Response& res)
{
return NULL;
}
}
+42
View File
@@ -0,0 +1,42 @@
#include "pch.h"
#include <iostream>
#include <limits>
#include <windows.h>
#include <string>
#include <cstdint>
namespace Daybreak::Utils {
std::wstring StringToWString(const std::string& str) {
if (str.empty()) return std::wstring();
int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0);
std::wstring wstrTo(size_needed, 0);
MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed);
return wstrTo;
}
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;
}
}
+34
View File
@@ -0,0 +1,34 @@
#include "pch.h"
#include "WhisperModule.h"
#include <GWCA/Managers/GameThreadMgr.h>
#include <GWCA/Managers/MapMgr.h>
#include <GWCA/Managers/ChatMgr.h>
#include <queue>
#include <string>
#include <Utils.h>
namespace Daybreak::Modules {
std::optional<bool> WhisperModule::GetPayload(std::wstring message) {
if (!GW::Map::GetIsMapLoaded()) {
return std::optional<bool>();
}
GW::Chat::WriteChat(GW::Chat::CHANNEL_WHISPER, message.c_str(), L"Daybreak", false);
return true;
}
std::string WhisperModule::ApiUri()
{
return "/whisper";
}
std::optional<std::wstring> WhisperModule::GetContext(const httplib::Request& req, httplib::Response& res)
{
auto wMessage = Utils::StringToWString(req.body);
return wMessage;
}
std::tuple<std::string, std::string> WhisperModule::ReturnPayload(bool) {
return std::make_tuple("", "text/plain");
}
}
+181
View File
@@ -0,0 +1,181 @@
// 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 "TitleInfoModule.h"
#include "WhisperModule.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.
const auto titleInfoModule = new Daybreak::Modules::TitleInfoModule();
const auto entityNameModule = new Daybreak::Modules::EntityNameModule();
const auto gameModule = new Daybreak::Modules::GameModule();
const auto gameStateModule = new Daybreak::Modules::GameStateModule();
const auto inventoryModule = new Daybreak::Modules::InventoryModule();
const auto itemNameModule = new Daybreak::Modules::ItemNameModule();
const auto loginModule = new Daybreak::Modules::LoginModule();
const auto mainPlayerModule = new Daybreak::Modules::MainPlayerModule();
const auto mapModule = new Daybreak::Modules::MapModule();
const auto pathingMetadataModule = new Daybreak::Modules::PathingMetadataModule();
const auto pathingModule = new Daybreak::Modules::PathingModule();
const auto preGameModule = new Daybreak::Modules::PreGameModule();
const auto sessionModule = new Daybreak::Modules::SessionModule();
const auto userModule = new Daybreak::Modules::UserModule();
const auto whisperModule = new Daybreak::Modules::WhisperModule();
http::server::SetLogger(http::ConsoleLogger);
http::server::Get("/alive", http::modules::HandleAlive);
http::server::Get("/id", http::modules::HandleProcessId);
http::server::Get(mapModule->ApiUri(), [&mapModule](const httplib::Request& req, httplib::Response& res) { mapModule->HandleApiCall(req, res); });
http::server::Get(loginModule->ApiUri(), [&loginModule](const httplib::Request& req, httplib::Response& res) { loginModule->HandleApiCall(req, res); });
http::server::Get(pathingMetadataModule->ApiUri(), [&pathingMetadataModule](const httplib::Request& req, httplib::Response& res) { pathingMetadataModule->HandleApiCall(req, res); });
http::server::Get(pathingModule->ApiUri(), [&pathingModule](const httplib::Request& req, httplib::Response& res) { pathingModule->HandleApiCall(req, res); });
http::server::Get(preGameModule->ApiUri(), [&preGameModule](const httplib::Request& req, httplib::Response& res) { preGameModule->HandleApiCall(req, res); });
http::server::Get(userModule->ApiUri(), [&userModule](const httplib::Request& req, httplib::Response& res) { userModule->HandleApiCall(req, res); });
http::server::Get(gameModule->ApiUri(), [&gameModule](const httplib::Request& req, httplib::Response& res) { gameModule->HandleApiCall(req, res); });
http::server::Get(inventoryModule->ApiUri(), [&inventoryModule](const httplib::Request& req, httplib::Response& res) { inventoryModule->HandleApiCall(req, res); });
http::server::Get(mainPlayerModule->ApiUri(), [&mainPlayerModule](const httplib::Request& req, httplib::Response& res) { mainPlayerModule->HandleApiCall(req, res); });
http::server::Get(gameStateModule->ApiUri(), [&gameStateModule](const httplib::Request& req, httplib::Response& res) { gameStateModule->HandleApiCall(req, res); });
http::server::Get(sessionModule->ApiUri(), [&sessionModule](const httplib::Request& req, httplib::Response& res) { sessionModule->HandleApiCall(req, res); });
http::server::Get(entityNameModule->ApiUri(), [&entityNameModule](const httplib::Request& req, httplib::Response& res) { entityNameModule->HandleApiCall(req, res); });
http::server::Get(itemNameModule->ApiUri(), [&itemNameModule](const httplib::Request& req, httplib::Response& res) { itemNameModule->HandleApiCall(req, res); });
http::server::Get(titleInfoModule->ApiUri(), [&titleInfoModule](const httplib::Request& req, httplib::Response& res) { titleInfoModule->HandleApiCall(req, res); });
http::server::Post(whisperModule->ApiUri(), [&whisperModule](const httplib::Request& req, httplib::Response& res) { whisperModule->HandleApiCall(req, res); });
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}
};
}
}
+16
View File
@@ -0,0 +1,16 @@
#pragma once
#include <payloads/Camera.h>
#include <cstdint>
#include <json.hpp>
using json = nlohmann::json;
namespace Daybreak {
void to_json(json& j, const Camera& p) {
j = json
{
{"Yaw", p.Yaw},
{"Pitch", p.Pitch}
};
}
}
@@ -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,15 @@
#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
{
{"Camera", p.Camera},
{"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,27 @@
#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},
{"RotationAngle", p.RotationAngle}
};
}
}
@@ -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}
};
}
}

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