Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 16 additions & 16 deletions ATTRIBUTION.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ work without, the projects and data sources below, which keep their own terms.
is **not affiliated with or endorsed by Grinding Gear Games in any way.**

Item names, modifier wordings, the clipboard format the game writes on Ctrl+C, and the stat
identifiers a trade query is built from are GGG's. None of it is baked into the binary it is
identifiers a trade query is built from are GGG's. None of it is baked into the binary - it is
downloaded at runtime from [PathOfPriceCheck-Data](https://github.com/JIRPOS/PathOfPriceCheck-Data),
whose [DATA-LICENSE.md](https://github.com/JIRPOS/PathOfPriceCheck-Data/blob/main/DATA-LICENSE.md)
states what that bundle contains and how it was derived. No game assets images, sounds, models
states what that bundle contains and how it was derived. No game assets - images, sounds, models -
are copied or redistributed anywhere in this project.

### How this client uses GGG's API
Expand All @@ -28,18 +28,18 @@ no API key, and never asks the user for account credentials.
`X-Rate-Limit-<policy>-State`, and `Retry-After` on a 429). Every GGG request goes through one
shared limiter that parses those headers, tracks each window, and **delays proactively** instead
of absorbing 429s. The server's own state counters outrank our tally, because they count every
client on the address the user's browser tab included.
client on the address - the user's browser tab included.
- **The limiter survives a restart.** An active restriction is written to disk and restored on the
next launch, so closing and reopening the application cannot be used accidentally or otherwise
to walk out of a lockout it never served.
next launch, so closing and reopening the application cannot be used - accidentally or
otherwise - to walk out of a lockout it never served.
- **Requests are made only when the user asks for them.** A price check parses and displays the
item without touching the network; the trade search is a button, and `auto_search` is off by
default. Static data (leagues, currency symbols) is cached for 24 hours and a week respectively.
- **It fetches in the batch sizes the API specifies** ten listing ids per `/fetch` request and
- **It fetches in the batch sizes the API specifies** - ten listing ids per `/fetch` request - and
asks only for as many listings as the user configured.
- **The in-game currency exchange feed is treated as its own thing.**
`web.poecdn.com/api/currency-exchange` is public and unauthenticated, and it is on the CDN rather
than the API host so it publishes no rate-limit policy, and it is deliberately *not* sent
than the API host - so it publishes no rate-limit policy, and it is deliberately *not* sent
through the limiter above, which exists to serve budgets this endpoint does not state. What
stands in for one is that a published hour never changes and one download covers every item in
every league: the cost is per hour of play rather than per price check, and a digest already on
Expand All @@ -50,8 +50,8 @@ is the route and it will be actioned. See [CONTACT.md](CONTACT.md).

## poe.ninja

The reference price row what a unique, a gem, a currency item or a base type is currently going
for comes from [poe.ninja](https://poe.ninja), used under its
The reference price row - what a unique, a gem, a currency item or a base type is currently going
for - comes from [poe.ninja](https://poe.ninja), used under its
[public API documentation](https://poe.ninja/docs/api).

- **Only the economy endpoints are touched.** The builds and profile endpoints are explicitly
Expand All @@ -65,14 +65,14 @@ for — comes from [poe.ninja](https://poe.ninja), used under its

## Path of Exile Wiki

The data bundle's per-unique modifier dataset which modifiers a given unique can roll, and which
of them come from a random pool is not in the game files. That grouping comes from
The data bundle's per-unique modifier dataset - which modifiers a given unique can roll, and which
of them come from a random pool - is not in the game files. That grouping comes from
[poewiki](https://www.poewiki.net)'s `item_mods` cargo table, licensed
**[CC BY-NC 3.0](https://creativecommons.org/licenses/by-nc/3.0/)**: attribution required,
non-commercial use only, which this project is.

The attribution string travels with the bundle rather than staying behind in the publisher's
repository the manifest carries it, the installer writes it through, and Settings renders it
repository - the manifest carries it, the installer writes it through, and Settings renders it -
because an attribution that does not reach the user is not an attribution.

## Tooling behind the data bundle
Expand Down Expand Up @@ -111,19 +111,19 @@ the typeface the game itself uses. Four faces are embedded in the executable.
Fontin is free for personal and commercial use, but its license nominally forbids redistribution
without the author's permission, which bundling into a released binary arguably is. That is a
deliberate maintainer decision with its reasoning written down in
[assets/fonts/README.md](assets/fonts/README.md), along with how to swap the typeface out it is
[assets/fonts/README.md](assets/fonts/README.md), along with how to swap the typeface out - it is
one generated file and no code change. `PPC_FONT_DIR` already overrides the embedded faces at
runtime. **If you are Jos Buivenga and would prefer this not be bundled, open an issue and it will
be removed.**

For text this project did not write trade account and character names, which are routinely
Cyrillic, Hangul or CJK, none of which Fontin covers a fallback face is loaded from **whatever
For text this project did not write - trade account and character names, which are routinely
Cyrillic, Hangul or CJK, none of which Fontin covers - a fallback face is loaded from **whatever
the operating system already ships**. Nothing is bundled for it and nothing is redistributed.

## Font Awesome Free

The buttons a word does not fit on are drawn in **[Font Awesome Free](https://fontawesome.com)**
Solid, by Fonticons, Inc. Only the codepoints actually used are bundled `scripts/fetch-glyphs.sh`
Solid, by Fonticons, Inc. Only the codepoints actually used are bundled - `scripts/fetch-glyphs.sh`
subsets the release down to those and no more, and
[assets/fonts/README.md](assets/fonts/README.md) says which and why. The website's navigation
icons are the same set, inlined into `site/style.css` rather than fetched from anywhere.
Expand Down
36 changes: 18 additions & 18 deletions BUILDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

There is no dependency manager to set up and nothing to vendor by hand: CMake's `FetchContent`
clones and builds SDL3, Dear ImGui, nlohmann/json and doctest from pinned tags in
[CMakeLists.txt](CMakeLists.txt). What the system has to provide is a compiler, CMake, git, and
on Linux the development headers those libraries compile against.
[CMakeLists.txt](CMakeLists.txt). What the system has to provide is a compiler, CMake, git, and -
on Linux - the development headers those libraries compile against.

```sh
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
Expand All @@ -19,13 +19,13 @@ of build tree. Every configure after that is cached.
| | minimum |
|---|---|
| CMake | 3.20 (4.x works) |
| Compiler | GCC 12+, Clang 15+, or MSVC 19.3x (Visual Studio 2022) C++20 |
| Compiler | GCC 12+, Clang 15+, or MSVC 19.3x (Visual Studio 2022) - C++20 |
| git | any; `FetchContent` shells out to it |
| Network | needed at configure time, for the dependency clones |

**libcurl is the one dependency taken from the system where there is one.** `find_package(CURL)`
decides: on Linux it finds the distro package listed below, and on Windows it finds nothing, so
curl and zlib are fetched and built statically against Schannel. That is deliberate it keeps the
curl and zlib are fetched and built statically against Schannel. That is deliberate - it keeps the
Windows release a single `.exe` with no DLL beside it and no CA bundle to ship.

## Linux
Expand All @@ -37,7 +37,7 @@ An X11 client, which under a Wayland session means Xwayland. See
continuously verified.** The others are its equivalents and are checked by hand; if one is wrong,
the CMake error names the header it could not find, and an issue about it is welcome.

### Arch and CachyOS, EndeavourOS, Manjaro
### Arch - and CachyOS, EndeavourOS, Manjaro

```sh
sudo pacman -S --needed base-devel cmake git \
Expand Down Expand Up @@ -66,7 +66,7 @@ sudo apt-get update && sudo apt-get install -y \
`apt` and `apt-get` take the same package names; use whichever your distribution prefers. Mint and
Pop!\_OS track the Ubuntu release they are built on, so the names are identical.

Version floors worth knowing: **Ubuntu 22.04** ships GCC 11 install `g++-12` and configure with
Version floors worth knowing: **Ubuntu 22.04** ships GCC 11 - install `g++-12` and configure with
`-DCMAKE_CXX_COMPILER=g++-12` if the build rejects C++20 constructs. **Debian 12** (bookworm, CMake
3.25 / GCC 12) is fine as shipped.

Expand All @@ -86,7 +86,7 @@ list; the rest is libcurl and the X11 extensions.
### SteamOS / Steam Deck

Untested, and two things are in the way rather than one. The root filesystem is read-only, so the
headers above cannot be installed onto it build inside a container (`distrobox`, `toolbox`) or
headers above cannot be installed onto it - build inside a container (`distrobox`, `toolbox`) or
just use the release tarball. Beyond that, the Deck's gaming session is gamescope rather than a
plain X11 session, and the global hotkey grab and overlay have not been tried against it.

Expand Down Expand Up @@ -118,7 +118,7 @@ ctest --test-dir build -C Release

The binary lands at `build\Release\PathOfPriceCheck.exe` and is self-contained: curl, zlib, SDL3
and the fonts are all linked in, and TLS goes through Schannel, so there is no OpenSSL and no CA
bundle to install. It is a **GUI-subsystem** executable nothing is printed to a console, because
bundle to install. It is a **GUI-subsystem** executable - nothing is printed to a console, because
a console-subsystem build would pop a window beside an application whose whole UI is an overlay
and a tray icon. Diagnostics go to the debug log instead (see below).

Expand All @@ -136,7 +136,7 @@ winget install JRSoftware.InnoSetup
iscc /DAppVersion=0.0.0 packaging\PathOfPriceCheck.iss
```

It installs per-user and unelevated, which is a decision rather than a convenience see
It installs per-user and unelevated, which is a decision rather than a convenience - see
[docs/updater.md](docs/updater.md) for what the updater does with it.

## Runtime requirements
Expand All @@ -146,7 +146,7 @@ It installs per-user and unelevated, which is a decision rather than a convenien
for the X11 backend outright rather than letting it choose. So it is an X11 client either way: on
a Wayland session it runs through **Xwayland**, which is how it is developed daily.

**There is no native Wayland backend and there will not be one.** Not "not yet" the reason is
**There is no native Wayland backend and there will not be one.** Not "not yet" - the reason is
the game, not the effort. Proton runs Path of Exile as an Xwayland client, and an X11 tool can
see every other Xwayland client: which window is in front, what it is called, where it is, and
where to send a synthetic keypress. None of that has a native-Wayland equivalent. A client cannot
Expand All @@ -157,7 +157,7 @@ It installs per-user and unelevated, which is a decision rather than a convenien
protocols involved as a matter of policy, so the result would not run there at all.

So going native would cost a windowing rewrite and a permanent three-compositor test matrix, and
buy a build that positions the panel *worse* than this one for as long as the game itself is an
buy a build that positions the panel *worse* than this one - for as long as the game itself is an
Xwayland client. This application's dependency on X11 is not stronger than Path of Exile's.

One caveat worth knowing under Wayland: copying in a **Wayland-native** application while the game
Expand All @@ -175,12 +175,12 @@ It installs per-user and unelevated, which is a decision rather than a convenien

| | |
|---|---|
| Both downloads | `glibc` 2.35+, `libstdc++`, `libX11`, and an OpenGL driver (`libglvnd`/`libGL`). SDL's X11 backend also loads `libXcursor`, `libXi`, `libXrandr` and `libxkbcommon` where they exist, and the tray icon needs GTK 3 with `libayatana-appindicator3` without it the app runs but has nothing to quit from. |
| Both downloads | `glibc` 2.35+, `libstdc++`, `libX11`, and an OpenGL driver (`libglvnd`/`libGL`). SDL's X11 backend also loads `libXcursor`, `libXi`, `libXrandr` and `libxkbcommon` where they exist, and the tray icon needs GTK 3 with `libayatana-appindicator3` - without it the app runs but has nothing to quit from. |
| Tarball only | `libcurl` and whichever TLS stack it was built against, plus `libXext`, `libXfixes` and `libXtst`. |

**That second row is the whole difference between the two downloads**: the AppImage bundles
libcurl with its TLS, compression and Kerberos tree and those three X extensions, and takes
everything in the first row from the host as it must, since libX11 and the GL driver
everything in the first row from the host - as it must, since libX11 and the GL driver
belong to the session, not to the application.
- **Windows 10 or later.** No runtime dependencies beyond the OS.
- **The game may be the native Windows client or Wine/Proton.** The copy path carries a good deal
Expand Down Expand Up @@ -209,8 +209,8 @@ Development environment variables, for iterating without the game running:

Captures to feed `PPC_DEV_ITEM` live in [`tests/data/examples/`](tests/data/examples).

**Only one copy runs at a time.** The first one to start takes a lock `flock` on
`<cache>/PathOfPriceCheck.lock`, a session-local named mutex on Windows and a second launch says
**Only one copy runs at a time.** The first one to start takes a lock - `flock` on
`<cache>/PathOfPriceCheck.lock`, a session-local named mutex on Windows - and a second launch says
so and exits. Both are released by the operating system when the process dies, so a crash leaves
nothing to clean up. This is not tidiness: two copies would both grab the global hotkeys (X11 hands
a passive grab to whoever asked first, so the *newly launched* one silently does nothing, which
Expand All @@ -224,8 +224,8 @@ ctest --test-dir build # all
ctest --test-dir build -R item_parse_test -V # one, verbose
```

Tests link `ppc_core` only the static library holding everything that needs neither a window nor
a network so they run headless, offline, and are the fast way to work on the parser, the data
Tests link `ppc_core` only - the static library holding everything that needs neither a window nor
a network - so they run headless, offline, and are the fast way to work on the parser, the data
layer, the query builder and the rate limiter. `ppc_core` links no SDL3, no ImGui, no X11 and no
libcurl, and that rule is worth keeping.

Expand All @@ -250,7 +250,7 @@ Both are committed, so a normal build needs neither.
```

The test fixtures under `tests/data/bundle/` are a slice of a real data release and are regenerated
by `./scripts/slice-test-bundle.py`, never edited by hand the `.index.bin` files address the
by `./scripts/slice-test-bundle.py`, never edited by hand - the `.index.bin` files address the
ndjson by byte offset, so one stray byte silently shifts every record out from under every lookup.

## Versioning
Expand Down
12 changes: 6 additions & 6 deletions CONTACT.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Contact

**[Open an issue.](https://github.com/JIRPOS/PathOfPriceCheck/issues)** That is the only contact
route, deliberately there is no email address to publish, and an issue is read.
route, deliberately - there is no email address to publish, and an issue is read.

PathOfPriceCheck identifies itself to the servers it talks to with this User-Agent:

Expand All @@ -18,18 +18,18 @@ tracker for anything about the data itself.

Open an issue and it will be actioned. This covers, non-exhaustively:

- **Grinding Gear Games** anything about this client's use of the public trade API, or about the
- **Grinding Gear Games** - anything about this client's use of the public trade API, or about the
game content the data bundle derives from. See [ATTRIBUTION.md](ATTRIBUTION.md) for what is used
and how, and the data repository's
[DATA-LICENSE.md](https://github.com/JIRPOS/PathOfPriceCheck-Data/blob/main/DATA-LICENSE.md)
for the bundle. No game assets are redistributed.
- **poe.ninja** anything about how their economy endpoints are queried or cached.
- **poewiki** anything about the CC BY-NC 3.0 modifier groupings or their attribution.
- **Jos Buivenga / exljbris** the Fontin faces embedded in the binary. Swapping the typeface out
- **poe.ninja** - anything about how their economy endpoints are queried or cached.
- **poewiki** - anything about the CC BY-NC 3.0 modifier groupings or their attribution.
- **Jos Buivenga / exljbris** - the Fontin faces embedded in the binary. Swapping the typeface out
is one generated file and no code change; see [assets/fonts/README.md](assets/fonts/README.md).
- Anyone else with a claim on something shipped here.

An issue does not have to be public-facing to be actioned, but it does have to be an issue
An issue does not have to be public-facing to be actioned, but it does have to be an issue -
there is no private channel, and pretending otherwise would be worse than saying so.

This project is not affiliated with or endorsed by Grinding Gear Games.
8 changes: 4 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

**This project is in early development and is not accepting pull requests.**

That is not a comment on anyone's code. The layers are still moving underneath each other the
That is not a comment on anyone's code. The layers are still moving underneath each other - the
item, trade and reference-price layers are built but their seams are being redrawn as the
remaining pieces land and reviewing patches against a design that changes weekly costs more than
remaining pieces land - and reviewing patches against a design that changes weekly costs more than
it produces, for both sides. A pull request opened today would likely sit until it stopped
applying, which is a worse outcome than not opening it.

Expand All @@ -26,11 +26,11 @@ are worth more than a patch would be right now:
fullscreen, windowed or borderless.
- **The copy hotkey doing nothing.** Turn on Settings → Diagnostics → debug log, reproduce it, and
quote the four-character check id from the panel footer (clicking it copies it). Read the log
before attaching it it contains whatever was on your clipboard. See [PRIVACY.md](PRIVACY.md).
before attaching it - it contains whatever was on your clipboard. See [PRIVACY.md](PRIVACY.md).

## Forking

The code is MIT ([LICENSE](LICENSE)) and fork away that is what it is for. Note that the fonts
The code is MIT ([LICENSE](LICENSE)) and fork away - that is what it is for. Note that the fonts
and the game data have terms of their own; [ATTRIBUTION.md](ATTRIBUTION.md) says what they are, and
they follow the code into a fork.

Expand Down
Loading