short-fuss / simco-utils

Utilities for Sim Companies
6 stars 2 forks source link

Use APIs instead of screenshots and textdumps for sales office analysis #1

Open harish1996 opened 3 years ago

harish1996 commented 3 years ago

The API "https://www.simcompanies.com/api/v2/players/me/buildings/" returns all the details of all the buildings of the player. I dont personally own a sales office, but for other buildings this API returns the current work done by the building and when it will finish, Similarly i hope there will be something for Sales Office also. It returns a convenient format compared to a text dump and far more reliable.

The API being player specific requires some workaround. I have tested the API using the cookie from my browser. In firefox, after logging into simcompanies, you can track the requests that the browser makes to the server. Ctrl + Shift + E or Hamburger menu ( top right menu ) -> Web Developer -> Network. In that if one filters for XHR requests, we can see the APIs that the browser is using. In those, if you click on an API and on the right side box that appears, if you notice there will be a Headers tab, which will contain the entire set of cookies our browser sends to the simcompanies server under Request header section. We can make use of this cookie, and send this cookie along with the GET request to access the above mentioned API. The cookie seems to stay alive for a long time. It might be required to generate a seperate cookie everytime we login though.

harish1996 commented 3 years ago

Here is a sample code which i tested the above API with.

import os
import argparse
import requests
import json

with open("cookie","r") as f:
    cookie = f.read()
    cookies = cookie.split(";")
    jar = {}
    for i in cookies:
        key, value = i.split("=")
        # print("{} : {}".format(key,value))
        jar[key] = value
    # print(jar)

with requests.Session() as r:
    r.cookies=requests.cookies.cookiejar_from_dict(jar)
    # out = r.get("https://www.simcompanies.com/api/v2/players/me/buildings/")
    # print(out.json())
    # out = r.get("https://www.simcompanies.com/api/v2/players/me/cashflow-statement/")
    # print(out.json())
    # link = "https://www.simcompanies.com/api/v3/players/me/past-finances/"
    # link = "https://www.simcompanies.com/api/v2/players/me/cashflow/100000000000/"
    # link = "https://www.simcompanies.com/api/v2/resources/"
    # link = "https://www.simcompanies.com/api/v2/contracts-incoming/"
    # link = "https://www.simcompanies.com/api/v2/contracts-outgoing/"
    # link = "https://www.simcompanies.com/api/v2/players/me/cashflow/"
    # link = "https://www.simcompanies.com/api/v2/players/me/market-orders"
    # link = "https://www.simcompanies.com/api/v2/players/me/research/"
    link = "https://www.simcompanies.com/api/v2/players/me/buildings/"
    out = r.get(link)
    print(json.dumps(out.json(), indent=4 ) )
    ls = out.json()
    # print(len(ls))

cookie is a file, which contains the entire cookie as a plaintext.

short-fuss commented 3 years ago

Thanks for contributing this issue! I reproduced your script and obtained the buildings detail. The only change I needed to make was:

key, value = i.split("=", 1)

This was because one of my cookies had a = in it, which meant that more than two outputs were produced.

I've yet to see the details associated with the Sales Office orders, because all of my SO are currently searching for contracts. Next time one has contracts, I'll re-run the script and see what outputs I get. Assuming this produces all the details shown on-screen (I guess it must do!), I agree that this approach has the major advantage of removing the need to do Select All -> Copy -> Paste -> Write text file. Instead run a single script to produce structured outputs.

The downsides are:

Probably the best approach for incorporating this enhancement would be to make a new script, maybe get_salesoffice.py, which does the work. It should produce the same output files as those produced by parse_salesoffice.py, so that they can be consumed by the same post-processing methods.

I haven't assigned anyone to address this issue yet. If you'd like to take it, feel free. However, since you don't use Sales Offices, that probably doesn't make sense!

harish1996 commented 3 years ago

I saw somewhere in stackoverflow that if cookies contained an = it might be a problem. Nice that you found a solution for that.

And regards to the python runtime thing on mobile, it is a quite challenging problem to solve especially if one is not willing to install stuff like Termux and all. I have been recently going through related stuff, and i noticed that one can convert a python flask application into a native android application through something called P4A. Maybe you can take a look.? I tried to use it, but my attempt failed.

harish1996 commented 3 years ago

The downsides are:

* Need each user to specify their cookie file

With respect to this problem tho, i dont think it is even solvable, considering that Patrik is against using browser automation tools for the game. Also i dont think there is any easier way to extract the cookie short of digging into the firefox/chrome's cookie storage location for these cookies.