mirror of
https://github.com/lutris/lutris
synced 2024-10-02 22:14:23 +00:00
First support for add-ons
This commit is contained in:
parent
4499c95566
commit
282ac32177
|
@ -20,6 +20,20 @@ If the game makes use of (Windows) Steam data, the value should be
|
|||
``$WINESTEAM:appid:path/to/data``. This will check that the data is available
|
||||
or install it otherwise.
|
||||
|
||||
Installer meta data
|
||||
===================
|
||||
|
||||
Installing mods and add-ons
|
||||
---------------------------
|
||||
|
||||
Mods and add-ons require that a base game is already available on the system.
|
||||
You can let now the installer that you want to install an add-on by specifying
|
||||
the ``requires`` directive. The value of ``requires`` must be the canonical
|
||||
slug name of a game, not one of its aliases. For example, to install the add-on
|
||||
"The reckoning" for Quake 2, you should add:
|
||||
|
||||
``requires: quake-2``
|
||||
|
||||
Writing the installation script
|
||||
===============================
|
||||
|
||||
|
|
|
@ -76,7 +76,11 @@ class ScriptInterpreter(object):
|
|||
raise ScriptingError("Invalid script", (self.script, self.errors))
|
||||
self.game_name = self.script.get('name')
|
||||
self.game_slug = slugify(self.game_name)
|
||||
self.target_path = self.default_target
|
||||
self.requires = self.script.get('requires')
|
||||
if self.requires:
|
||||
self._check_dependecy()
|
||||
else:
|
||||
self.target_path = self.default_target
|
||||
|
||||
@property
|
||||
def default_target(self):
|
||||
|
@ -84,6 +88,14 @@ class ScriptInterpreter(object):
|
|||
games_dir = lutris_config.get_path() or os.path.expanduser('~')
|
||||
return join(games_dir, self.game_slug)
|
||||
|
||||
def _check_dependecy(self):
|
||||
game = pga.get_game_by_slug(self.requires)
|
||||
if not game or not game['directory']:
|
||||
raise ScriptingError(
|
||||
"You need to install {} before".format(self.requires)
|
||||
)
|
||||
self.target_path = game['directory']
|
||||
|
||||
def _fetch_script(self, game_ref):
|
||||
if os.path.exists(game_ref):
|
||||
script_contents = open(game_ref, 'r').read()
|
||||
|
@ -230,7 +242,10 @@ class ScriptInterpreter(object):
|
|||
'realname': self.script['name'],
|
||||
'runner': runner_name
|
||||
}
|
||||
pga.add_game(self.script['name'], runner_name, slug=self.game_slug)
|
||||
pga.add_game(self.script['name'],
|
||||
runner_name,
|
||||
slug=self.game_slug,
|
||||
directory=self.target_path)
|
||||
if 'system' in self.script:
|
||||
config_data['system'] = self.script['system']
|
||||
if runner_name in self.script:
|
||||
|
@ -503,38 +518,45 @@ class InstallerDialog(Gtk.Dialog):
|
|||
|
||||
# Interpreter
|
||||
self.interpreter = ScriptInterpreter(game_ref, self)
|
||||
self.interpreter.is_valid()
|
||||
|
||||
## GUI Setup
|
||||
|
||||
# Top label
|
||||
# Title label
|
||||
self.status_label = Gtk.Label()
|
||||
self.status_label.set_markup('<b>Select installation directory:</b>')
|
||||
self.status_label.set_alignment(0, 0)
|
||||
self.status_label.set_padding(20, 0)
|
||||
self.vbox.add(self.status_label)
|
||||
self.status_label.set_markup("<b>Installing %s</b>"
|
||||
% self.interpreter.game_name)
|
||||
|
||||
# Main widget box
|
||||
self.widget_box = Gtk.VBox()
|
||||
self.widget_box.set_margin_right(25)
|
||||
self.widget_box.set_margin_left(25)
|
||||
self.vbox.pack_start(self.widget_box, True, True, 10)
|
||||
|
||||
# Target chooser
|
||||
default_path = self.interpreter.default_target
|
||||
location_entry = FileChooserEntry(default=default_path)
|
||||
location_entry.entry.connect('changed', self.on_target_changed)
|
||||
self.widget_box.pack_start(location_entry, False, False, 10)
|
||||
|
||||
# Separator
|
||||
self.vbox.pack_start(Gtk.HSeparator(), True, True, 10)
|
||||
self.vbox.pack_start(Gtk.HSeparator(), False, False, 0)
|
||||
|
||||
# Install button
|
||||
self.install_button = Gtk.Button('Install')
|
||||
self.install_button.connect('clicked', self.on_install_clicked)
|
||||
|
||||
self.action_buttons = Gtk.Alignment.new(0.95, 0.1, 0.15, 0)
|
||||
self.action_buttons = Gtk.Alignment.new(0.95, 0, 0.15, 0)
|
||||
self.action_buttons.add(self.install_button)
|
||||
|
||||
self.vbox.pack_start(self.action_buttons, False, False, 0)
|
||||
self.vbox.pack_start(self.action_buttons, False, False, 25)
|
||||
|
||||
# Target chooser
|
||||
if not self.interpreter.requires:
|
||||
# Top label
|
||||
label = Gtk.Label()
|
||||
label.set_markup('<b>Select installation directory:</b>')
|
||||
label.set_alignment(0, 0)
|
||||
self.widget_box.pack_start(label, False, False, 10)
|
||||
default_path = self.interpreter.default_target
|
||||
location_entry = FileChooserEntry(default=default_path)
|
||||
location_entry.entry.connect('changed', self.on_target_changed)
|
||||
self.widget_box.pack_start(location_entry, False, False, 0)
|
||||
else:
|
||||
label = Gtk.Label("Click install to continue")
|
||||
self.show_all()
|
||||
|
||||
def on_target_changed(self, text_entry):
|
||||
|
|
|
@ -76,12 +76,20 @@ def get_games(name_filter=None):
|
|||
return game_list
|
||||
|
||||
|
||||
def add_game(name, runner, slug=None):
|
||||
def get_game_by_slug(slug):
|
||||
game_result = sql.db_select(PGA_DB, "games", condition=('slug', slug))
|
||||
if game_result:
|
||||
return game_result[0]
|
||||
|
||||
|
||||
def add_game(name, runner, slug=None, directory=None):
|
||||
"""Adds a game to the PGA database."""
|
||||
if not slug:
|
||||
slug = slugify(name)
|
||||
sql.db_insert(PGA_DB, "games",
|
||||
{'name': name, 'slug': slug, 'runner': runner})
|
||||
game_data = {'name': name, 'slug': slug, 'runner': runner}
|
||||
if directory:
|
||||
game_data['directory'] = directory
|
||||
sql.db_insert(PGA_DB, "games", game_data)
|
||||
|
||||
|
||||
def delete_game(name):
|
||||
|
|
|
@ -34,10 +34,22 @@ def db_delete(db_path, table, field, value):
|
|||
(value,))
|
||||
|
||||
|
||||
def db_select(db_path, table, fields):
|
||||
field_names = ", ".join(fields)
|
||||
def db_select(db_path, table, fields=None, condition=None):
|
||||
if fields:
|
||||
field_names = ", ".join(fields)
|
||||
else:
|
||||
field_names = "*"
|
||||
print field_names
|
||||
with db_cursor(db_path) as cursor:
|
||||
cursor.execute("SELECT {0} FROM {1}".format(field_names, table))
|
||||
if condition:
|
||||
assert len(condition) == 2
|
||||
cursor.execute(
|
||||
"SELECT {0} FROM {1} where {2}=?".format(
|
||||
field_names, table, condition[0]
|
||||
), (condition[1], )
|
||||
)
|
||||
else:
|
||||
cursor.execute("SELECT {0} FROM {1}".format(field_names, table))
|
||||
rows = cursor.fetchall()
|
||||
column_names = [column[0] for column in cursor.description]
|
||||
results = []
|
||||
|
|
Loading…
Reference in a new issue