implement gog functionality for install scripts

This commit is contained in:
Nico Linder 2018-08-02 07:28:07 +02:00 committed by Mathieu Comandon
parent 0e601a6e31
commit 1cf5bb0f87
3 changed files with 97 additions and 7 deletions

View file

@ -118,7 +118,7 @@ class GogWindow(Gtk.Window):
game_details = self.gog_service.get_game_details(game['id'])
installer_liststore = Gtk.ListStore(str, str)
installers = game_details['downloads']['installers']
for index, installer in enumerate(installers):
for _, installer in enumerate(installers):
installer_liststore.append(
(installer['id'], "{} ({}, {})".format(installer['name'], installer['language_full'], installer['os']))
)

View file

@ -24,6 +24,8 @@ from lutris.config import LutrisConfig, make_game_config_id
from lutris.installer.errors import ScriptingError
from lutris.installer.commands import CommandsMixin
from lutris.services.gog import is_connected as is_gog_connected, connect as connect_gog, GogService
from lutris.runners import (
wine, winesteam, steam, import_runner,
InvalidRunner, NonInstallableRunnerError, RunnerInstallationError
@ -96,7 +98,7 @@ class ScriptInterpreter(CommandsMixin):
if not self.is_valid():
raise ScriptingError("Invalid script: \n{}".format("\n".join(self.errors)), self.script)
self.files = self.script.get('files', [])
self.files :list = self.script.get('files', [])
self.requires = self.script.get('requires')
self.extends = self.script.get('extends')
@ -141,7 +143,7 @@ class ScriptInterpreter(CommandsMixin):
if self.runner in ('steam', 'winesteam'):
# Steam games installs in their steamapps directory
return False
if self.files:
if self.files or self.script['game']['gog']:
return True
command_names = [list(c.keys())[0] for c in self.script.get('installer', [])]
if 'insert-disc' in command_names:
@ -248,6 +250,27 @@ class ScriptInterpreter(CommandsMixin):
# "Get the files" stage
# ---------------------
def prepare_game_files(self):
# Add gog installer to files
if self.script["game"]["gog"]:
data = self.get_gog_downloadlink()
gogUrl = data[0]
self.gog_data["os"] = data[1]
file = {
"installer": {
"url": gogUrl,
"filename": gogUrl.split("?")[0].split("/")[-1]
}
}
self.files.append(file)
if self.gog_data["os"] == "linux":
file = {
"unzip": "http://lutris.net/files/tools/unzip.tar.gz"
}
self.files.append(file)
self.iter_game_files()
def iter_game_files(self):
if self.files:
# Create cache dir if needed
@ -379,7 +402,7 @@ class ScriptInterpreter(CommandsMixin):
def install_runners(self):
if not self.runners_to_install:
self.iter_game_files()
self.prepare_game_files()
else:
runner = self.runners_to_install.pop(0)
self.install_runner(runner)
@ -411,7 +434,7 @@ class ScriptInterpreter(CommandsMixin):
"Can't continue installation without file", file_id
)
self.game_files[file_id] = file_path
self.iter_game_files()
self.prepare_game_files()
# ---------------
# "Commands" stage
@ -440,6 +463,36 @@ class ScriptInterpreter(CommandsMixin):
if self.runner == 'winesteam' else 'linux'
commands.insert(0, 'install_steam_game')
self.script['installer'] = commands
# Add gog installation to commands, if it's a GOG and linux game
if self.gog_data and self.gog_data["os"] == "linux":
commands :list = self.script.get('installer', [])
gogcommands = []
gogcommands.append({
"extract": {
"dst": "$CACHE",
"file": "$unzip"
}
})
gogcommands.append({
"execute": {
"args": '$installer -d "$GAMEDIR" "data/noarch/*"',
"description": "Extracting game data, it will take a while...",
"file": "$CACHE/unzip"
}
})
gogcommands.append({
"rename": {
"dst": "$GAMEDIR/Game",
"src": "$GAMEDIR/data/noarch"
}
})
gogcommands.extend(commands)
self.script['installer'] = gogcommands
if not self.script.get('exe', False):
self.script['exe'] = "Game/start.sh"
self._iter_commands()
def _iter_commands(self, result=None, exception=None):
@ -783,7 +836,7 @@ class ScriptInterpreter(CommandsMixin):
data_path, self.steam_data['steam_rel_path']
)
)
self.iter_game_files()
self.prepare_game_files()
def _download_steam_data(self, file_uri, file_id):
"""Download the game files from Steam to use them outside of Steam.
@ -827,3 +880,40 @@ class ScriptInterpreter(CommandsMixin):
self.parent.set_status('Getting Steam game data')
self.steam_data['platform'] = "linux"
self.install_steam_game(steam.steam, is_game_files=True)
# -----------
# GOG stuff
# -----------
def get_gog_downloadlink(self) -> (str, str):
"""Get url of a gog installer."""
self.gog_data = self.script['game']['gog']
if not is_gog_connected():
connect_gog()
gog_service = GogService()
game_details = gog_service.get_game_details(self.gog_data['appid'])
installer = self._get_gog_installer(game_details)
if installer[0]:
installer = installer[1]
for game_file in installer.get('files', []):
downlink = game_file.get("downlink")
if not downlink:
logger.error("No download information for %s", installer)
continue
download_info = gog_service.get_download_info(downlink)
return (download_info['downlink'], installer["os"])
else:
logger.error("Installer with id %s not found!", self.gog_data['installerid'])
raise ScriptingError("Given installer id not existing!")
def _get_gog_installer(self, game_details):
installers = game_details['downloads']['installers']
for _, installer in enumerate(installers):
logger.debug("Found gog installer with id: %s", installer['id'])
print(installer)
if installer['id'] == self.gog_data['installerid']:
return (True, installer)
return (False, "")

View file

@ -15,7 +15,7 @@ NAME = "GOG"
class GogService:
"""Service clas for GOG"""
"""Service class for GOG"""
name = "GOG"
embed_url = 'https://embed.gog.com'
api_url = 'https://api.gog.com'