Skip to content

Commit

Permalink
v 0.5.0: fetch owned games from Wargaming.net account
Browse files Browse the repository at this point in the history
  • Loading branch information
Mixaill committed Jul 7, 2019
1 parent e629cfc commit f69f01c
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 23 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ GOG Galaxy 2.0 Wargaming Game Center integration

## Changelog

* v. 0.5.0
* Fetch owned games from Wargaming.net account

* v. 0.4.5
* Improve Wargaming.net authorization error processing

Expand Down
2 changes: 1 addition & 1 deletion manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "Galaxy Wargaming plugin",
"platform": "wargaming",
"guid": "91728e8a-33c3-4b6d-8382-4dd31043dec1",
"version": "0.4.5",
"version": "0.5.0",
"description": "Galaxy Wargaming plugin",
"author": "Mikhail Paulyshka",
"email": "[email protected]",
Expand Down
10 changes: 6 additions & 4 deletions plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,13 @@ async def get_local_games(self):
return self._localgames.get_local_games()

async def get_owned_games(self):
owned_games = list()
for game in self._wgc.get_owned_applications().values():
owned_games.append(Game(game.GetId(), game.GetName(), None, LicenseInfo(LicenseType.FreeToPlay, None)))
owned_applications = list()

return owned_games
for application in self._wgc.get_owned_applications():
for instance_id, instance_name in application.get_application_instances().items():
owned_applications.append(Game(instance_id, instance_name, None, LicenseInfo(LicenseType.FreeToPlay, None)))

return owned_applications

async def launch_game(self, game_id):
game = self._localgames.GetWgcGame(game_id)
Expand Down
2 changes: 1 addition & 1 deletion version.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "0.4.5"
__version__ = "0.5.0"
30 changes: 20 additions & 10 deletions wgc/wgc.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
import xml.etree.ElementTree as ElementTree

from .wgc_api import WGCApi
from .wgc_application import WGCApplication
from .wgc_application_local import WGCLocalApplication
from .wgc_application_owned import WGCOwnedApplication
from .wgc_location import WGCLocation

class WGC():
def __init__(self):
self._api = WGCApi(self.get_tracking_id(), self.get_country_code())
self._api = WGCApi(self.get_tracking_id(), self.get_country_code(), self.get_wgc_language())
pass

#General
Expand Down Expand Up @@ -49,16 +50,26 @@ def account_nickname(self) -> str:
def account_realm(self) -> str:
return self._api.get_account_realm()

# Tracking
# Settings

def get_country_code(self) -> str:
def __get_preferences_value(self, node_name: str) -> str:
wgc_preferences_file = WGCLocation.get_wgc_preferences_file()
if os.path.exists(wgc_preferences_file):
xml_file = ElementTree.parse(wgc_preferences_file).getroot()
return xml_file.find('application/user_location_country_code').text
return xml_file.find(node_name).text

return ''

def get_wgc_language(self) -> str:
return self.__get_preferences_value('application/localization_manager/current_localization')


def get_country_code(self) -> str:
return self.__get_preferences_value('application/user_location_country_code')


# Tracking

def get_tracking_id(self) -> str:
tracking_id = ''

Expand All @@ -69,14 +80,13 @@ def get_tracking_id(self) -> str:

return tracking_id

def get_local_applications(self) -> Dict[str, WGCApplication]:
def get_local_applications(self) -> Dict[str, WGCLocalApplication]:
apps = dict()
for app_dir in WGCLocation.get_apps_dirs():
app = WGCApplication(app_dir)
app = WGCLocalApplication(app_dir)
apps[app.GetId()] = app

return apps

def get_owned_applications(self) -> Dict[str, WGCApplication]:
#TODO: implement fetching owned application from WGCPS
return self.get_local_applications()
def get_owned_applications(self) -> Dict[str, WGCOwnedApplication]:
return self._api.fetch_product_list()
93 changes: 91 additions & 2 deletions wgc/wgc_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@
import pprint
import threading
from urllib.parse import parse_qs
from typing import Dict
from typing import Dict, List

from Crypto.Hash import keccak
import requests

from .wgc_application_owned import WGCOwnedApplication
from .wgc_constants import WGCAuthorizationResult, WGCRealms


class WGCAuthorizationServer(BaseHTTPRequestHandler):
backend = None

Expand Down Expand Up @@ -137,13 +139,16 @@ class WGCApi:

WGCPS_FETCH_PRODUCT_INFO = '/platform/api/v1/fetchProductList'
WGCPS_LOGINSESSION = '/auth/api/v1/loginSession'

WGUSCS_SHOWROOM = '/api/v15/content/showroom/'

LOCALSERVER_HOST = '127.0.0.1'
LOCALSERVER_PORT = 13337

def __init__(self, tracking_id : str = '', country_code : str = ''):
def __init__(self, tracking_id : str = '', country_code : str = '', language_code : str = 'en'):
self._tracking_id = tracking_id
self._country_code = country_code
self._language_code = language_code

self._server_thread = None
self._server_object = None
Expand Down Expand Up @@ -561,3 +566,87 @@ def __wgni_get_account_info(self):

return json.loads(response.text)

#
# Fetch product list
#

def fetch_product_list(self) -> List[WGCOwnedApplication]:
product_list = list()

additional_gameurls = list()
for game_data in self.__wgcps_fetch_product_list()['data']['product_content']:
wgc_data = game_data['metadata']['wgc']
additional_gameurls.append('%s@%s' % (wgc_data['application_id']['data'], wgc_data['update_url']['data']))

showroom_data = self.__wguscs_get_showroom(additional_gameurls)
if showroom_data is None:
logging.error('wgc_api/fetch_product_list: error on retrieving showroom data')
return product_list

for product in showroom_data['showcase']:
product_list.append(WGCOwnedApplication(product))

return product_list


def __wgcps_fetch_product_list(self):
if self._login_info is None:
logging.error('wgc_auth/__wgcps_fetch_product_list: login info is none')
return None

if 'realm' not in self._login_info:
logging.error('wgc_auth/__wgcps_fetch_product_list: login info does not contain realm')
return None

response = self._session.post(
self.__get_url('wgcps', self._login_info['realm'], self.WGCPS_FETCH_PRODUCT_INFO),
json = { 'account_id' : self.get_account_id(), 'country' : self._country_code, 'storefront' : 'wgc_showcase' })

while response.status_code == 202:
response = self._session.get(response.headers['Location'])

if response.status_code != 200:
logging.error('wgc_auth/__wgcps_fetch_product_list: error on retrieving account info: %s' % response.text)
return None

response_content = json.loads(response.text)

#load additional adata
response_content['data']['product_content'] = list()
for product_uri in response_content['data']['product_uris']:
product_response = self._session.get(product_uri)
if response.status_code != 200:
logging.error('wgc_auth/__wgcps_fetch_product_list: error on retrieving product info: %s' % product_uri)
continue

response_content['data']['product_content'].append(json.loads(product_response.text))

return response_content


def __wguscs_get_showroom(self, additional_urls : List[str] = None):
if self._login_info is None:
logging.error('wgc_auth/__wguscs_get_showroom: login info is none')
return None

if 'realm' not in self._login_info:
logging.error('wgc_auth/__wguscs_get_showroom: login info does not contain realm')
return None

additionals = ''
if additional_urls:
additionals = '&showcase_products=' + str.join('&showcase_products=', additional_urls)

url = self.__get_url('wguscs', self._login_info['realm'], self.WGUSCS_SHOWROOM)
url = url + '?lang=%s' % self._language_code.upper()
url = url + '&gameid=WGC.RU.PRODUCTION&format=json'
url = url + '&country_code=%s' % self._country_code
url = url + additionals

showroom_response = self._session.get(url)

if showroom_response.status_code != 200:
logging.error('wgc_auth/__wguscs_get_showroom: error on retrieving showroom data: %s' % response.text)
return None

return json.loads(showroom_response.text)
2 changes: 1 addition & 1 deletion wgc/wgc_application.py → wgc/wgc_application_local.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from .wgc_helper import is_mutex_exists

class WGCApplication():
class WGCLocalApplication():
DETACHED_PROCESS = 0x00000008
INFO_FILE = 'game_info.xml'
METADATA_FILE = 'game_metadata\\metadata.xml'
Expand Down
17 changes: 17 additions & 0 deletions wgc/wgc_application_owned.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from typing import Dict

class WGCOwnedApplication():

def __init__(self, data):
self._data = data
pass

def get_application_name(self) -> str:
return self._data['game_name']

def get_application_instances(self) -> Dict[str, str]:
result = dict()
for instance in self._data['instances']:
result[instance['application_id']] = '%s (%s)' % (self.get_application_name(), instance['realm_id'])

return result
8 changes: 4 additions & 4 deletions wgc/wgc_constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ class WGCAuthorizationResult(Enum):


WGCRealms = {
'RU' : {'domain_wgnet': 'ru.wargaming.net' , 'domain_wgcps' : 'wgcps-ru.wargaming.net' , 'client_id': '77cxLwtEJ9uvlcm2sYe4O8viIIWn1FEWlooMTTqF'},
'EU' : {'domain_wgnet': 'eu.wargaming.net' , 'domain_wgcps' : 'wgcps-eu.wargaming.net' , 'client_id': 'JJ5yuABVKqZekaktUR8cejMzxbbHAtUVmY2eamsS'},
'NA' : {'domain_wgnet': 'na.wargaming.net' , 'domain_wgcps' : 'wgcps-na.wargaming.net' , 'client_id': 'AJ5PLrEuz5C2d0hHmmjQJtjaMpueSahYY8CiswHE'},
'ASIA' : {'domain_wgnet': 'asia.wargaming.net', 'domain_wgcps' : 'wgcps-asia.wargaming.net', 'client_id': 'Xe2oDM8Z6A4N70VZIV8RyVLHpvdtVPYNRIIYBklJ'},
'RU' : {'domain_wgnet': 'ru.wargaming.net' , 'domain_wgcps' : 'wgcps-ru.wargaming.net' , 'domain_wguscs' : 'wguscs-wotru.wargaming.net', 'client_id': '77cxLwtEJ9uvlcm2sYe4O8viIIWn1FEWlooMTTqF'},
'EU' : {'domain_wgnet': 'eu.wargaming.net' , 'domain_wgcps' : 'wgcps-eu.wargaming.net' , 'domain_wguscs' : 'wguscs-wotru.wargaming.net', 'client_id': 'JJ5yuABVKqZekaktUR8cejMzxbbHAtUVmY2eamsS'},
'NA' : {'domain_wgnet': 'na.wargaming.net' , 'domain_wgcps' : 'wgcps-na.wargaming.net' , 'domain_wguscs' : 'wguscs-wotru.wargaming.net', 'client_id': 'AJ5PLrEuz5C2d0hHmmjQJtjaMpueSahYY8CiswHE'},
'ASIA' : {'domain_wgnet': 'asia.wargaming.net', 'domain_wgcps' : 'wgcps-asia.wargaming.net', 'domain_wguscs' : 'wguscs-wotru.wargaming.net', 'client_id': 'Xe2oDM8Z6A4N70VZIV8RyVLHpvdtVPYNRIIYBklJ'},
}

0 comments on commit f69f01c

Please sign in to comment.