blha303 revised this gist . Go to revision
1 file changed, 15 insertions, 2 deletions
docs.md
| @@ -1,3 +1,5 @@ | |||
| 1 | + | The server returns `X-Powered-By: Lara Croft` for each response, cool easter egg. | |
| 2 | + | ||
| 1 | 3 | ### On game start | |
| 2 | 4 | ||
| 3 | 5 | The game sends several requests in the opening videos. In the below documentation, text in curly braces (\{\}) is shorthand for `{ "d": {"os_Ping": ... } }` where os_Ping is the current endpoint being accessed and ... is the contents of the curly braces. | |
| @@ -13,11 +15,12 @@ Necessary headers for each request (may vary, untested): | |||
| 13 | 15 | * `OS-System: linux`, ditto | |
| 14 | 16 | ||
| 15 | 17 | 1. `/game/os_Ping` | |
| 16 | - | * Likely confirming that the service is up, needs to succeed otherwise the game marks itself as offline | |
| 18 | + | * Likely confirming that the service is up | |
| 17 | 19 | * Returns `{ 6739 }`, different number each time | |
| 18 | 20 | ||
| 19 | 21 | 2. `/game/os_GetServiceInfo` | |
| 20 | - | * This returns information about the IP address used for connection: city name, country code, ip, lat, long, phone region code, zip code if available. Also returns a list of metadata, e.g client config and list of endpoints. Example output [here](https://gist.github.com/blha303/8c5b925f95c23c08197ac3a82e1bee15). | |
| 22 | + | * Returns information about the IP address used for connection and a list of metadata and endpoints. | |
| 23 | + | * Example output: https://gist.github.com/blha303/8c5b925f95c23c08197ac3a82e1bee15 | |
| 21 | 24 | ||
| 22 | 25 | 3. `/game/os_Ping` again | |
| 23 | 26 | ||
| @@ -39,6 +42,16 @@ Necessary headers for each request (may vary, untested): | |||
| 39 | 42 | * Query params: `b_digital`, a boolean, probably whether it's digital or a physical disc; `i16_episode`, the episode number of the current save game; `s_locale`, language code e.g 'en' | |
| 40 | 43 | * Example response: https://gist.github.com/blha303/d00b1c34728cc21101b7fc198bbf3371 | |
| 41 | 44 | ||
| 45 | + | 8. `/game/SetUserProfileFriends` | |
| 46 | + | * Sends list of UIDs for user's friends list | |
| 47 | + | * POST requests, `["UID", ...]` | |
| 48 | + | * Returns `{ 0 }`, friends service probably disabled | |
| 49 | + | ||
| 50 | + | 9. `/game/GetSeasonPassOfferIdList` | |
| 51 | + | * No clue what this is for, you'd think it would show information on the episodes but it just returns the same thing five times. | |
| 52 | + | * Query params: `s_region`, mine says 'na', not applicable? | |
| 53 | + | * Returns https://gist.github.com/blha303/cba709bc7b9db5e8122c46133fdedbcb | |
| 54 | + | ||
| 42 | 55 | ### Occasionally | |
| 43 | 56 | ||
| 44 | 57 | 1. `/game/AddMetrics` | |
blha303 revised this gist . Go to revision
1 file changed, 8 insertions, 6 deletions
docs.md
| @@ -39,6 +39,13 @@ Necessary headers for each request (may vary, untested): | |||
| 39 | 39 | * Query params: `b_digital`, a boolean, probably whether it's digital or a physical disc; `i16_episode`, the episode number of the current save game; `s_locale`, language code e.g 'en' | |
| 40 | 40 | * Example response: https://gist.github.com/blha303/d00b1c34728cc21101b7fc198bbf3371 | |
| 41 | 41 | ||
| 42 | + | ### Occasionally | |
| 43 | + | ||
| 44 | + | 1. `/game/AddMetrics` | |
| 45 | + | * Is called every few minutes regardless of the client configuration returned by `os_GetServiceInfo` | |
| 46 | + | * POST request, https://gist.github.com/blha303/b79ba499a2ea61880d3fc8dc812f7eb4 | |
| 47 | + | * Returns nothing at all | |
| 48 | + | ||
| 42 | 49 | ### On opening the choices screen (from the main menu or after each episode) | |
| 43 | 50 | ||
| 44 | 51 | 1. `/game/CommunityFactsGetEpisode` | |
| @@ -55,12 +62,7 @@ Necessary headers for each request (may vary, untested): | |||
| 55 | 62 | ||
| 56 | 63 | Making me listen to Obstacles again >_< | |
| 57 | 64 | ||
| 58 | - | 1. `/game/AddMetrics` | |
| 59 | - | * Unsure of significance given that UpdateUserProfileGameSpecific gives more succinct information | |
| 60 | - | * POST request, https://gist.github.com/blha303/b79ba499a2ea61880d3fc8dc812f7eb4 | |
| 61 | - | * Returns nothing at all | |
| 62 | - | ||
| 63 | - | 2. `/game/UpdateUserProfileGameSpecific` | |
| 65 | + | 1. `/game/UpdateUserProfileGameSpecific` | |
| 64 | 66 | * POST request, summarizes choices made. Called when credits start | |
| 65 | 67 | * JSON data, https://gist.github.com/blha303/144499eeb67dface9a83371c17f9513b | |
| 66 | 68 | * Returns `{ 0 }`, maybe means profile isn't updated when the given UID has already completed the given chapter | |
blha303 revised this gist . Go to revision
1 file changed, 20 insertions, 3 deletions
docs.md
| @@ -7,7 +7,7 @@ Necessary headers for each request (may vary, untested): | |||
| 7 | 7 | * `Accept: application/json`, otherwise the API returns XML (obviously if you're fine with that you can omit this) | |
| 8 | 8 | * `OS-AuthProvider: 6`, unsure of the purpose of this | |
| 9 | 9 | * `OS-AuthTicketData: [string]`, begins with CAEQ on my copy of the game, unsure if variable | |
| 10 | - | * `OS-AuthTicketSize: 44`, not the length of the above auth ticket as the initial ticket is much longer | |
| 10 | + | * `OS-AuthTicketSize: 44`, the length of the above string | |
| 11 | 11 | * `OS-UID: [string]`, steam user ID, or some other form of identification in standalone versions probably | |
| 12 | 12 | * `OS-Platform: steam`, the user's platform, needs more testing to get options | |
| 13 | 13 | * `OS-System: linux`, ditto | |
| @@ -31,14 +31,15 @@ Necessary headers for each request (may vary, untested): | |||
| 31 | 31 | 6. `/game/CreateUserProfile` | |
| 32 | 32 | * Square Enix login again? Probably making sure that there's an account for the given steam ID for stats collection even if it isn't linked to a SEM account | |
| 33 | 33 | * Query params: `s_uid` is my steam user ID | |
| 34 | - | * Returns `{ true }` | |
| 34 | + | * Returns `{ true }` and a header `OS-AuthResponse` containing the new `OS-AuthTicketData` to be used for subsequent requests | |
| 35 | 35 | ||
| 36 | 36 | 7. `/game/GetTodaysInfocast` | |
| 37 | 37 | * Returns a list of messages to be scrolled at the bottom of the main menu | |
| 38 | + | * Idling on the menu calls this periodically | |
| 38 | 39 | * Query params: `b_digital`, a boolean, probably whether it's digital or a physical disc; `i16_episode`, the episode number of the current save game; `s_locale`, language code e.g 'en' | |
| 39 | 40 | * Example response: https://gist.github.com/blha303/d00b1c34728cc21101b7fc198bbf3371 | |
| 40 | 41 | ||
| 41 | - | ### On opening the choices menu item | |
| 42 | + | ### On opening the choices screen (from the main menu or after each episode) | |
| 42 | 43 | ||
| 43 | 44 | 1. `/game/CommunityFactsGetEpisode` | |
| 44 | 45 | * Returns a list of choices for a given episode, and the percentage and raw numbers for each choice | |
| @@ -49,3 +50,19 @@ Necessary headers for each request (may vary, untested): | |||
| 49 | 50 | * Apparently would return the same as `/game/CommunityFactsGetEpisode` with additional info on friend stats, but currently returns nothing | |
| 50 | 51 | * Query params: `i16_episode`, the given episode number; `s_uid`, the steam/other user id | |
| 51 | 52 | * Currently returns `{ "d": {"results": [] } }` | |
| 53 | + | ||
| 54 | + | ### On finishing an episode | |
| 55 | + | ||
| 56 | + | Making me listen to Obstacles again >_< | |
| 57 | + | ||
| 58 | + | 1. `/game/AddMetrics` | |
| 59 | + | * Unsure of significance given that UpdateUserProfileGameSpecific gives more succinct information | |
| 60 | + | * POST request, https://gist.github.com/blha303/b79ba499a2ea61880d3fc8dc812f7eb4 | |
| 61 | + | * Returns nothing at all | |
| 62 | + | ||
| 63 | + | 2. `/game/UpdateUserProfileGameSpecific` | |
| 64 | + | * POST request, summarizes choices made. Called when credits start | |
| 65 | + | * JSON data, https://gist.github.com/blha303/144499eeb67dface9a83371c17f9513b | |
| 66 | + | * Returns `{ 0 }`, maybe means profile isn't updated when the given UID has already completed the given chapter | |
| 67 | + | ||
| 68 | + | No API requests upon completing an achievement. | |
blha303 revised this gist . Go to revision
1 file changed, 51 insertions, 3 deletions
docs.md
| @@ -1,3 +1,51 @@ | |||
| 1 | - | * `/game/CommunityFactsGetEpisode` | |
| 2 | - | * Query param `i16_episode`: episode number (e.g 1,2,3,4,5) | |
| 3 | - | * Returns xml unless header `Accept: application/json` is specified | |
| 1 | + | ### On game start | |
| 2 | + | ||
| 3 | + | The game sends several requests in the opening videos. In the below documentation, text in curly braces (\{\}) is shorthand for `{ "d": {"os_Ping": ... } }` where os_Ping is the current endpoint being accessed and ... is the contents of the curly braces. | |
| 4 | + | ||
| 5 | + | Necessary headers for each request (may vary, untested): | |
| 6 | + | ||
| 7 | + | * `Accept: application/json`, otherwise the API returns XML (obviously if you're fine with that you can omit this) | |
| 8 | + | * `OS-AuthProvider: 6`, unsure of the purpose of this | |
| 9 | + | * `OS-AuthTicketData: [string]`, begins with CAEQ on my copy of the game, unsure if variable | |
| 10 | + | * `OS-AuthTicketSize: 44`, not the length of the above auth ticket as the initial ticket is much longer | |
| 11 | + | * `OS-UID: [string]`, steam user ID, or some other form of identification in standalone versions probably | |
| 12 | + | * `OS-Platform: steam`, the user's platform, needs more testing to get options | |
| 13 | + | * `OS-System: linux`, ditto | |
| 14 | + | ||
| 15 | + | 1. `/game/os_Ping` | |
| 16 | + | * Likely confirming that the service is up, needs to succeed otherwise the game marks itself as offline | |
| 17 | + | * Returns `{ 6739 }`, different number each time | |
| 18 | + | ||
| 19 | + | 2. `/game/os_GetServiceInfo` | |
| 20 | + | * This returns information about the IP address used for connection: city name, country code, ip, lat, long, phone region code, zip code if available. Also returns a list of metadata, e.g client config and list of endpoints. Example output [here](https://gist.github.com/blha303/8c5b925f95c23c08197ac3a82e1bee15). | |
| 21 | + | ||
| 22 | + | 3. `/game/os_Ping` again | |
| 23 | + | ||
| 24 | + | 4. `/game/SEM_Login` | |
| 25 | + | * Probably for the Square Enix account login | |
| 26 | + | * Query params: `s_type` is 'UID' here; `s_value` is my steam user ID, a long string of digits | |
| 27 | + | * Returns `{ "__metadata": { "type": "game.SEMSubmit" }, "b_confirmed": true, "s_SEMID": "string of numbers", "s_email": "email address", "s_facebookID": "probably facebook user identifier", "s_longTermToken": "string of numbers and letters" }` | |
| 28 | + | ||
| 29 | + | 5. It sends the above request twice, unclear why | |
| 30 | + | ||
| 31 | + | 6. `/game/CreateUserProfile` | |
| 32 | + | * Square Enix login again? Probably making sure that there's an account for the given steam ID for stats collection even if it isn't linked to a SEM account | |
| 33 | + | * Query params: `s_uid` is my steam user ID | |
| 34 | + | * Returns `{ true }` | |
| 35 | + | ||
| 36 | + | 7. `/game/GetTodaysInfocast` | |
| 37 | + | * Returns a list of messages to be scrolled at the bottom of the main menu | |
| 38 | + | * Query params: `b_digital`, a boolean, probably whether it's digital or a physical disc; `i16_episode`, the episode number of the current save game; `s_locale`, language code e.g 'en' | |
| 39 | + | * Example response: https://gist.github.com/blha303/d00b1c34728cc21101b7fc198bbf3371 | |
| 40 | + | ||
| 41 | + | ### On opening the choices menu item | |
| 42 | + | ||
| 43 | + | 1. `/game/CommunityFactsGetEpisode` | |
| 44 | + | * Returns a list of choices for a given episode, and the percentage and raw numbers for each choice | |
| 45 | + | * Query params: `i16_episode`, the given episode number | |
| 46 | + | * Example response for episode 1: https://gist.github.com/blha303/cec90d1d2e351c33d39ddddd880cd252 | |
| 47 | + | ||
| 48 | + | 2. `/game/GetFriendsProfileStats` | |
| 49 | + | * Apparently would return the same as `/game/CommunityFactsGetEpisode` with additional info on friend stats, but currently returns nothing | |
| 50 | + | * Query params: `i16_episode`, the given episode number; `s_uid`, the steam/other user id | |
| 51 | + | * Currently returns `{ "d": {"results": [] } }` | |
Steven Smith revised this gist . Go to revision
1 file changed, 16 insertions
whats-needed.md(file created)
| @@ -0,0 +1,16 @@ | |||
| 1 | + | Logging tests for what headers are necessary. | |
| 2 | + | ||
| 3 | + | ``` | |
| 4 | + | $ curl https://lis.os.eidos.com/game/CommunityFactsGetEpisode?i16_episode=3 | |
| 5 | + | {"s_ErrorsCodes":"501","s_ErrorsMessages":"Invalid","s_ErrorsDetails":"Missing mandatory authentication headers: (OS-AuthProvider)."} | |
| 6 | + | $ curl -H "Accept: application/json" -H "OS-AuthProvider: 6" https://lis.os.eidos.com/game/CommunityFactsGetEpisode?i16_episode=3 | |
| 7 | + | {"s_ErrorsCodes":"501","s_ErrorsMessages":"Invalid","s_ErrorsDetails":"Missing mandatory authentication headers: (OS-AuthTicketSize, OS-AuthTicketData|OS-AuthTokenData)."} | |
| 8 | + | $ curl -H "Accept: application/json" -H "OS-AuthProvider: 6" -H "OS-AuthTicketData: [redacted]" -H "OS-AuthTicketSize: 44" https://lis.os.eidos.com/game/CommunityFactsGetEpisode?i16_episode=3 | |
| 9 | + | {"s_ErrorsCodes":"501","s_ErrorsMessages":"Invalid","s_ErrorsDetails":"No UID header found."} | |
| 10 | + | $ curl -H "Accept: application/json" -H "OS-AuthProvider: 6" -H "OS-AuthTicketData: [redacted]" -H "OS-AuthTicketSize: 44" -H "OS-UID: [redacted]" https://lis.os.eidos.com/game/CommunityFactsGetEpisode?i16_episode=3 | |
| 11 | + | {"s_ErrorsCodes":"801","s_ErrorsMessages":"Missing Header","s_ErrorsDetails":"HTTP header OS-Platform is required."} | |
| 12 | + | $ curl -H "Accept: application/json" -H "OS-AuthProvider: 6" -H "OS-AuthTicketData: [redacted]" -H "OS-AuthTicketSize: 44" -H "OS-UID: [redacted]" -H "OS-Platform: steam" https://lis.os.eidos.com/game/CommunityFactsGetEpisode?i16_episode=3 | |
| 13 | + | {"s_ErrorsCodes":"800","s_ErrorsMessages":"Invalid Header","s_ErrorsDetails":"Header OS-Platform=steam and header OS-System=null are not compatible. Either neither value or both values must be specified. If both values are specified, they must be compatible with eachother."} | |
| 14 | + | $ curl -H "Accept: application/json" -H "OS-AuthProvider: 6" -H "OS-AuthTicketData: [redacted]" -H "OS-AuthTicketSize: 44" -H "OS-UID: [redacted]" -H "OS-Platform: steam" -H "OS-System: linux" https://lis.os.eidos.com/game/CommunityFactsGetEpisode?i16_episode=3 | |
| 15 | + | {"d" : {"results" : [{"__metadata" : {"uri" : "https://lis.os.eidos.com/game/communityfactreturns('AddedNameToVortex')", "type" : "game.communityfactreturn"}, "f_rate" : "0.610894941634241", "i64_totalCount" : 514, "i64_trueCount" : 314, "i16_ep" : 3, "s_factID" : "AddedNameToVortex"}, ... | |
| 16 | + | ``` | |
Steven Smith revised this gist . Go to revision
1 file changed, 3 insertions
docs.md(file created)
| @@ -0,0 +1,3 @@ | |||
| 1 | + | * `/game/CommunityFactsGetEpisode` | |
| 2 | + | * Query param `i16_episode`: episode number (e.g 1,2,3,4,5) | |
| 3 | + | * Returns xml unless header `Accept: application/json` is specified | |
Steven Smith revised this gist . Go to revision
1 file changed, 12 insertions, 12 deletions
revlis.md
| @@ -7,18 +7,18 @@ First, you'll need a copy of Life Is Strange on Steam. Second, you'll need to ha | |||
| 7 | 7 | * Edit `.steam/steam/steamapps/common/Life Is Strange/LifeIsStrange.sh` on the first machine, and edit the lines below `HAS_CURL` like so: | |
| 8 | 8 | ||
| 9 | 9 | ``` | |
| 10 | - | \#HAS_CURL=$( command -v curl-config ) | |
| 11 | - | \#if [ -n "$... | |
| 12 | - | \# SSL_CERT_FILE=... | |
| 13 | - | \#else | |
| 14 | - | \# if ... | |
| 15 | - | \# SSL_CERT... | |
| 16 | - | \# elif | |
| 17 | - | \# SSL_CERT... | |
| 18 | - | \# elif | |
| 19 | - | \# SSL_CERT... | |
| 20 | - | \# fi | |
| 21 | - | \#fi | |
| 10 | + | #HAS_CURL=$( command -v curl-config ) | |
| 11 | + | #if [ -n "$... | |
| 12 | + | # SSL_CERT_FILE=... | |
| 13 | + | #else | |
| 14 | + | # if ... | |
| 15 | + | # SSL_CERT... | |
| 16 | + | # elif | |
| 17 | + | # SSL_CERT... | |
| 18 | + | # elif | |
| 19 | + | # SSL_CERT... | |
| 20 | + | # fi | |
| 21 | + | #fi | |
| 22 | 22 | export SSL_CERT_FILE="/home/user/Downloads/mitmproxy-ca-cert.pem" | |
| 23 | 23 | ``` | |
| 24 | 24 | ||
Steven Smith revised this gist . Go to revision
1 file changed, 2 insertions
revlis.md
| @@ -6,6 +6,7 @@ First, you'll need a copy of Life Is Strange on Steam. Second, you'll need to ha | |||
| 6 | 6 | * Set up transparent proxying http://docs.mitmproxy.org/en/stable/transparent/linux.html | |
| 7 | 7 | * Edit `.steam/steam/steamapps/common/Life Is Strange/LifeIsStrange.sh` on the first machine, and edit the lines below `HAS_CURL` like so: | |
| 8 | 8 | ||
| 9 | + | ``` | |
| 9 | 10 | \#HAS_CURL=$( command -v curl-config ) | |
| 10 | 11 | \#if [ -n "$... | |
| 11 | 12 | \# SSL_CERT_FILE=... | |
| @@ -19,6 +20,7 @@ First, you'll need a copy of Life Is Strange on Steam. Second, you'll need to ha | |||
| 19 | 20 | \# fi | |
| 20 | 21 | \#fi | |
| 21 | 22 | export SSL_CERT_FILE="/home/user/Downloads/mitmproxy-ca-cert.pem" | |
| 23 | + | ``` | |
| 22 | 24 | ||
| 23 | 25 | * Set the second computer as the default gateway on the first computer by running `sudo ip route add default via <ip>`. Get the ip address of the second computer by running `ip addr | grep inet`. | |
| 24 | 26 | * Close other programs (except Terminal and Steam) to minimize noise | |
Steven Smith revised this gist . Go to revision
1 file changed, 12 insertions, 12 deletions
revlis.md
| @@ -6,18 +6,18 @@ First, you'll need a copy of Life Is Strange on Steam. Second, you'll need to ha | |||
| 6 | 6 | * Set up transparent proxying http://docs.mitmproxy.org/en/stable/transparent/linux.html | |
| 7 | 7 | * Edit `.steam/steam/steamapps/common/Life Is Strange/LifeIsStrange.sh` on the first machine, and edit the lines below `HAS_CURL` like so: | |
| 8 | 8 | ||
| 9 | - | #HAS_CURL=$( command -v curl-config ) | |
| 10 | - | #if [ -n "$... | |
| 11 | - | # SSL_CERT_FILE=... | |
| 12 | - | #else | |
| 13 | - | # if ... | |
| 14 | - | # SSL_CERT... | |
| 15 | - | # elif | |
| 16 | - | # SSL_CERT... | |
| 17 | - | # elif | |
| 18 | - | # SSL_CERT... | |
| 19 | - | # fi | |
| 20 | - | #fi | |
| 9 | + | \#HAS_CURL=$( command -v curl-config ) | |
| 10 | + | \#if [ -n "$... | |
| 11 | + | \# SSL_CERT_FILE=... | |
| 12 | + | \#else | |
| 13 | + | \# if ... | |
| 14 | + | \# SSL_CERT... | |
| 15 | + | \# elif | |
| 16 | + | \# SSL_CERT... | |
| 17 | + | \# elif | |
| 18 | + | \# SSL_CERT... | |
| 19 | + | \# fi | |
| 20 | + | \#fi | |
| 21 | 21 | export SSL_CERT_FILE="/home/user/Downloads/mitmproxy-ca-cert.pem" | |
| 22 | 22 | ||
| 23 | 23 | * Set the second computer as the default gateway on the first computer by running `sudo ip route add default via <ip>`. Get the ip address of the second computer by running `ip addr | grep inet`. | |
Steven Smith revised this gist . Go to revision
1 file changed, 59 insertions
revlis.md(file created)
| @@ -0,0 +1,59 @@ | |||
| 1 | + | Hello! Today I thought I'd take on the task of reverse engineering the stats screen in Life Is Strange so I could easily request and display the data without needing to start the game. I'm documenting it here for future use, since nobody else seems to have tried this yet. | |
| 2 | + | ||
| 3 | + | First, you'll need a copy of Life Is Strange on Steam. Second, you'll need to have it working on Linux. The Linux Steam version of LIS has a startup script that sets the ssl certificate locations, you'll need to modify that to be able to MITM the server connections. The game makes requests to https://lis.os.eidos.com, but doesn't verify the certificate in the game. (requests to Feral Interactive, the company that ported LIS to OSX and Linux, do seem to be verified, but they don't matter much) | |
| 4 | + | ||
| 5 | + | * Set up mitmproxy on a laptop or other second computer that won't be running the game: http://docs.mitmproxy.org/en/stable/install.html | |
| 6 | + | * Set up transparent proxying http://docs.mitmproxy.org/en/stable/transparent/linux.html | |
| 7 | + | * Edit `.steam/steam/steamapps/common/Life Is Strange/LifeIsStrange.sh` on the first machine, and edit the lines below `HAS_CURL` like so: | |
| 8 | + | ||
| 9 | + | #HAS_CURL=$( command -v curl-config ) | |
| 10 | + | #if [ -n "$... | |
| 11 | + | # SSL_CERT_FILE=... | |
| 12 | + | #else | |
| 13 | + | # if ... | |
| 14 | + | # SSL_CERT... | |
| 15 | + | # elif | |
| 16 | + | # SSL_CERT... | |
| 17 | + | # elif | |
| 18 | + | # SSL_CERT... | |
| 19 | + | # fi | |
| 20 | + | #fi | |
| 21 | + | export SSL_CERT_FILE="/home/user/Downloads/mitmproxy-ca-cert.pem" | |
| 22 | + | ||
| 23 | + | * Set the second computer as the default gateway on the first computer by running `sudo ip route add default via <ip>`. Get the ip address of the second computer by running `ip addr | grep inet`. | |
| 24 | + | * Close other programs (except Terminal and Steam) to minimize noise | |
| 25 | + | * Run `mitmdump -w output.mitmdump` in Terminal, then start Life Is Strange through Steam | |
| 26 | + | * I had to alt-tab out and into the game to get it to work, you may need to do the same | |
| 27 | + | * You should see requests to /game/os\_Ping start showing up. mitmdump will record all game communication. I loaded up the main menu, clicked on Choices, waited for the stats to show up, then closed the game and killed mitmdump with ctrl-c | |
| 28 | + | * Run `mitmproxy --host -r output.mitmdump` to view the requests. | |
| 29 | + | ||
| 30 | + | If only the stats server communications weren't encrypted, would have been a lot easier. | |
| 31 | + | ||
| 32 | + | I'm not sure how initial authentication works, the game sends an OS-AuthTicketData header with a string of characters, maybe each copy of the game has a unique auth ticket. It also requests user location data via an IP info lookup (/game/os\_GetServiceInfo) and sends your friends list in the form of a list of user IDs (/game/SetUserProfileFriends), presumably for the friend stats response (/game/GetFriendsProfileStats) but this currently returns nothing. The main thing I'm interested in is /game/CommunityFactsGetEpisode, which takes a query param of i16\_episode={episode number} and returns json: | |
| 33 | + | ||
| 34 | + | "d" : { | |
| 35 | + | "results" : [ | |
| 36 | + | { | |
| 37 | + | "__metadata" : { | |
| 38 | + | "uri" : "https://lis.os.eidos.com/game/communityfactreturns('BirdDead')", | |
| 39 | + | "type" : "game.communityfactreturn" | |
| 40 | + | }, | |
| 41 | + | "f_rate" : "0.638969873663751", | |
| 42 | + | "i64_totalCount" : 2058, | |
| 43 | + | "i64_trueCount" : 1315, | |
| 44 | + | "i16_ep" : 1, | |
| 45 | + | "s_factID" : "BirdDead" | |
| 46 | + | }, | |
| 47 | + | { | |
| 48 | + | "__metadata" : { | |
| 49 | + | "uri" : "https://lis.os.eidos.com/game/communityfactreturns('BirdSaved')", | |
| 50 | + | "type" : "game.communityfactreturn" | |
| 51 | + | }, | |
| 52 | + | "f_rate" : "0.361030126336249", | |
| 53 | + | "i64_totalCount" : 2058, | |
| 54 | + | "i64_trueCount" : 743, | |
| 55 | + | "i16_ep" : 1, | |
| 56 | + | "s_factID" : "BirdSaved" | |
| 57 | + | }, ... | |
| 58 | + | ||
| 59 | + | Which is exactly what I was looking for \^_\^ | |