Open Aeonitis opened 5 months ago
As I understand it, the itch.io server-side and OAuth APIs are for sellers to provide integration for games, and there isn't a way to use it for getting games you bought, generate download URLs, etc. The official itch app (https://github.com/itchio/itch) uses butler, but the APIs it uses require running it as a JSON-RPC daemon.
The butlerd docs are available at https://docs.itch.ovh/butlerd/master/, but as a general reference, getting authenticated works like such:
butler --json \
--user-agent "test app (Linux)" \
daemon \
--dbpath ".../path/to/butler.db"
Meta.Authenticate
with the secret provided over stdout.Profile.List
and Profile.UseSavedLogin
. If you get a profile this way, you're done! Skip to step 7.Profile.LoginWithPassword
.[^pw]Profile.LoginWithPassword
returns, you may receive a couple server->client calls, Profile.RequestCaptcha
and/or Profile.RequestTOTP
.
Profile.RequestTOTP
is simple: ask the user for the TOTP token, and respond.Profile.RequestCaptcha
is, bluntly, a mess. More on that in a moment.Profile.LoginWithPassword
returns with the logged in profile.profileId
field, for use in later requests (e.g. Fetch.GameRecords
).For Profile.RequestCaptcha
, you'll be provided a recaptchaUrl
, most likely https://itch.io/captcha
. This page needs to be embedded as a BrowserView or new window (not an iframe[^frame]) where you can inject JS to catch the CAPTCHA response. For example:
// function called by itch's reCAPTCHA on success.
// otherwise you could watch document.getElementById("g-recaptcha-response")
function onRecaptcha(response) {
// "namespace" our message so we don't try to consume a stray Steam message
window.opener.postMessage("__ITCH_CAPTCHA_" + response, "*");
}
Once solved, you can return the response string in the RPC call.
The other API calls are pretty straightforward, but handling two-way JSON-RPC in shell scripts would be a challenge. Logs are also sent through JSON-RPC calls, so you'd likely want at least one long-lived TCP connection to output them.
[^pw]: I was able to pull this off with a modal dialog. It doesn't feel great, but it works...
[^frame]: https://itch.io/captcha
sets X-Frame-Options: SAMEORIGIN
, so we can't embed it in a frame.
Is your feature request related to a problem? Please describe. Integration of Itch.io games into the Junkstore plugin. First of all, I love all your work here!
I would love to do this but I am unfortunately busy on my own non-steam app :'( Just adding this here so you can correct me, and make it easier for others to jump in and smash it into reality. No rush in responding, take your time!
Draft Plan
Next Steps
Current Observations [Epic Integration]
Login
How the third-party in-game-mode browser user login is handled for other stores (Epic)...
Login
setup initiated via Plugin in main.py https://github.com/ebenbruyns/junkstore/blob/e115250dad6dbf9d4a1201a8d92982087b32b980/main.py#L240 static.json button https://github.com/ebenbruyns/junkstore/blob/e115250dad6dbf9d4a1201a8d92982087b32b980/defaults/scripts/Extensions/Epic/static.json#L88Epic
and the actionlogin
Epic_login
store.sh https://github.com/ebenbruyns/junkstore/blob/e115250dad6dbf9d4a1201a8d92982087b32b980/defaults/scripts/Extensions/Epic/store.sh#L308 where the steam env variables ensure the environment specific to Steam context is correctly set https://github.com/ebenbruyns/junkstore/blob/e115250dad6dbf9d4a1201a8d92982087b32b980/defaults/scripts/shared.sh#L200 and it moves on to https://github.com/ebenbruyns/junkstore/blob/e115250dad6dbf9d4a1201a8d92982087b32b980/defaults/scripts/Extensions/Epic/store.sh#L312to construct a JSON for login...
Uses tool to authenticate via CLI on Epic specific launcher Legendary https://github.com/ebenbruyns/junkstore/blob/e115250dad6dbf9d4a1201a8d92982087b32b980/defaults/scripts/Extensions/Epic/login.sh#L13
Arg info from Legendary documentation -v, --debug means Set loglevel to debug
Current Auth ID data in game logs, stored as appId.log e.g.
cd1b8a6********************cf7b7f536.log
which is 'Night in the Woods'.Client caching on deck is handled by sqlite 3:
https://github.com/ebenbruyns/junkstore/blob/befe4d055035c5dddcf933af21f077f8b442fe6d/defaults/scripts/shared/GamesDb.py#L2 & https://github.com/ebenbruyns/junkstore/blob/befe4d055035c5dddcf933af21f077f8b442fe6d/defaults/scripts/shared/GameSet.py#L10
Questions
Fundamental questions here to help make the process easier for whichever dev takes on some of this work, based on what I learned from skimming through the repo and especially this commit
Describe the solution we'd like
API integration
Sample Shell Script:
Sample Python Code:
Scripting and Configuration Adjustments
defaults/scripts/Extensions/Itch/store.sh
:defaults/scripts/itch-config.py
:Backend Python Modifications
defaults/scripts/itch.py
:defaults/scripts/shared/GameSet.py
andGamesDb.py
:Database Schema Enhancement
Frontend Integration
src/Components/GameDetailsItem.tsx
:Again, my two cents just to push us a little forward, Keep up the awesome work :D