Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
UncleGoogle committed Jul 22, 2019
2 parents f411963 + f8dab9d commit 7f75ce6
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 22 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
.env
galaxy/
info.md
credentials.data
credentials*

# Byte-compiled / optimized / DLL files
__pycache__/
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,15 @@ This plugin is currenly in early development stage.

## Installation

Unpack `humblebundle_v{}.zip` asset from latest [release][1] to:
- (WINDOWS) `%localappdata%\GOG.com\Galaxy\plugins\installed`
- (MACOS) `~/Library/Application Support/GOG.com/Galaxy/plugins/installed`

or build from source code (python3.6 or higher required):

1. `git clone --recursive https://github.com/UncleGoogle/galaxy-integration-humblebundle.git`
2. `cd galaxy-integration-humblebundle`
3. `python tasks.py install`
4. `python tasks.py dist`

[1]: https://github.com/UncleGoogle/galaxy-integration-humblebundle/releases
23 changes: 17 additions & 6 deletions src/plugin.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import sys
import time
import asyncio
import os
import json
import logging
Expand Down Expand Up @@ -43,10 +45,11 @@ async def authenticate(self, stored_credentials=None):
return Authentication(user_id, user_name)

async def pass_login_credentials(self, step, credentials, cookies):
logging.debug(json.dumps(cookies, indent=2))
auth_cookie = next(filter(lambda c: c['name'] == '_simpleauth_sess', cookies))
self.store_credentials(auth_cookie)

user_id, user_name = await self._api.authenticate(auth_cookie)
self.store_credentials(auth_cookie)
return Authentication(user_id, user_name)

async def get_owned_games(self):
Expand All @@ -57,12 +60,20 @@ def is_game(sub):

games = {}
gamekeys = await self._api.get_gamekeys()
for gamekey in gamekeys:
details = await self._api.get_order_details(gamekey)
# logging.info(f'Parsing details of order {gamekey}:\n{json.dumps(details, indent=4)}')
requests = [self._api.get_order_details(x) for x in gamekeys]

logging.info(f'Fetching info about {len(requests)} orders started...')
all_games_details = await asyncio.gather(*requests)
logging.info('Fetching info finished')

for details in all_games_details:
for sub in details['subproducts']:
if is_game(sub):
games[sub['machine_name']] = HumbleGame(sub)
try:
if is_game(sub):
games[sub['machine_name']] = HumbleGame(sub)
except Exception as e:
logging.error(f'Error while parsing subproduct {sub}: {repr(e)}')
continue

self._games = games
return [g.in_galaxy_format() for g in games.values()]
Expand Down
2 changes: 1 addition & 1 deletion src/version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.1"
__version__ = "0.1.2"
22 changes: 15 additions & 7 deletions src/webservice.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,26 @@ async def _request(self, *args, **kwargs):

def _decode_user_id(self, _simpleauth_sess):
info = _simpleauth_sess.split('|')[0]
# get rid of escape characters
info = bytes(info, "utf-8").decode("unicode_escape")
info_padded = info + '=='
decoded = json.loads(base64.b64decode(info_padded))
logging.debug(decoded)
logging.debug(f'user info cookie: {info}')
info += '==' # ensure full padding
decoded = json.loads(base64.b64decode(info))
return decoded['user_id']

async def authenticate(self, auth_cookie: dict):
# recreate original cookie
cookie = SimpleCookie()
cookie[auth_cookie['name']] = auth_cookie['value']
cookie_val = bytes(auth_cookie['value'], "utf-8").decode("unicode_escape")
# some users have cookies with escaped characters, some not...
# for the first group strip quotes:
cookie_val = cookie_val.replace('"', '')
cookie[auth_cookie['name']] = cookie_val

user_id = self._decode_user_id(cookie_val)
self._session.cookie_jar.update_cookies(cookie)
user_id = self._decode_user_id(auth_cookie['value'])

# check if auth session is valid
await self.get_gamekeys()

return (user_id, user_id)

async def get_gamekeys(self):
Expand Down
19 changes: 12 additions & 7 deletions test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,20 @@
from pathlib import Path
import asyncio


CREDENTIALS_FILE = "credentials.data"


if __name__ == "__main__":

async def run_server_connection(reader, writer):

credentials = ""
path = Path("credentials.data")
path = Path(CREDENTIALS_FILE)
if not path.exists():
path.touch()

with open("credentials.data", "r") as f:
with open(CREDENTIALS_FILE, "r") as f:
data = f.read()
if data:
credentials = json.loads(data)
Expand All @@ -37,15 +41,16 @@ async def run_server_connection(reader, writer):
tokens = json.loads(tokens.decode())
try:
if 'method' in tokens and tokens['method'] == 'store_credentials':
with open('credentials.data', 'w') as f:
print(f'overwriting {CREDENTIALS_FILE}')
with open(CREDENTIALS_FILE, 'w') as f:
f.write(json.dumps(tokens['params']))

print("tokens", tokens)
ret = await reader.readline()
print("ret", ret)
except Exception as e:
print(f'{str(e)}: Removing credentials')
os.remove('credentials.data')
print(f'{str(e)}.\n Probably you need refresh it?')


print("owned")
writer.write(b'{"jsonrpc": "2.0", "id": "3", "method": "import_owned_games"}\n')
Expand All @@ -59,8 +64,8 @@ async def run_server_connection(reader, writer):
# ret = await reader.readline()
# print("ret", ret)

print("install_game")
writer.write(b'{"jsonrpc": "2.0", "method": "install_game", "params":{"game_id": "samorost2"}}\n')
# print("install_game")
# writer.write(b'{"jsonrpc": "2.0", "method": "install_game", "params":{"game_id": "samorost2"}}\n')

# print("launch_game")
# writer.write(b'{"jsonrpc": "2.0", "method": "launch_game", "params":{"game_id": "samorost2"}}\n')
Expand Down

0 comments on commit 7f75ce6

Please sign in to comment.