Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow installing Windows versions of games that support Linux #590

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
**1.2.6**
- Fix changing the install path causing an exception
- Allow Windows versions of games with Linux versions to be installed (thanks to makson96 and Kzimir)
- Fix error detection & reporting on wineprefix creation failure (thanks to LeXofLeviafan)

**1.2.5**
Expand Down
67 changes: 60 additions & 7 deletions data/ui/properties.ui
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
<property name="can-focus">False</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
Expand All @@ -35,13 +35,12 @@
<property name="spacing">6</property>
<property name="homogeneous">True</property>
<child>
<!-- n-columns=2 n-rows=11 -->
<object class="GtkGrid">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="margin-top">18</property>
<property name="row-spacing">6</property>
<property name="column-spacing">12</property>
<property name="row-homogeneous">True</property>
<property name="column-homogeneous">True</property>
<child>
<object class="GtkButton" id="button_properties_regedit">
Expand Down Expand Up @@ -297,7 +296,7 @@
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">10</property>
<property name="top-attach">11</property>
</packing>
</child>
<child>
Expand All @@ -311,7 +310,7 @@
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">9</property>
<property name="top-attach">10</property>
</packing>
</child>
<child>
Expand All @@ -323,11 +322,65 @@
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">10</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label_properties_platform">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">Game platform:</property>
<property name="justify">fill</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">9</property>
</packing>
</child>
<child>
<placeholder/>
<object class="GtkButtonBox" id="game_type">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="halign">start</property>
<property name="orientation">vertical</property>
<property name="layout-style">center</property>
<child>
<object class="GtkRadioButton" id="radiobutton_linux_type">
<property name="label" translatable="yes">Linux (native)</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="active">True</property>
<property name="draw-indicator">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="radiobutton_windows_type">
<property name="label" translatable="yes">Windows (wine)</property>
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">False</property>
<property name="active">True</property>
<property name="draw-indicator">True</property>
<property name="group">radiobutton_linux_type</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">9</property>
</packing>
</child>
</object>
<packing>
Expand Down
16 changes: 14 additions & 2 deletions minigalaxy/api.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -100,14 +100,17 @@ def get_library(self):
# Only support Linux unless the show_windows_games setting is enabled
if product["worksOn"]["Linux"]:
platform = "linux"
supported_platforms = [platform, "windows"]
elif self.config.show_windows_games:
platform = "windows"
supported_platforms = [platform]
else:
continue
if not product["url"]:
logger.warn("{} ({}) has no store page url".format(product["title"], product['id']))
game = Game(name=product["title"], url=product["url"], game_id=product["id"],
image_url=product["image"], platform=platform, category=product["category"])
image_url=product["image"], platform=platform,
category=product["category"], supported_platforms=supported_platforms)
games.append(game)
if current_page == total_pages:
all_pages_processed = True
Expand Down Expand Up @@ -144,7 +147,7 @@ def get_info(self, game: Game) -> dict:
return response

# This returns a unique download url and a link to the checksum of the download
def get_download_info(self, game: Game, operating_system="linux", dlc_installers="") -> dict:
def get_download_info(self, game: Game, operating_system="", dlc_installers="") -> dict:
if dlc_installers:
installers = dlc_installers
else:
Expand Down Expand Up @@ -227,6 +230,15 @@ def get_user_info(self) -> str:
self.config.username = username
return username

def get_download_version(self, game: Game):
if not game.get_info("platform"):
platform_version = game.platform
else:
platform_version = game.get_info("platform")
if not platform_version:
platform_version = "linux"
return platform_version

def get_version(self, game: Game, gameinfo=None, dlc_name="") -> str:
if gameinfo is None:
gameinfo = self.get_info(game)
Expand Down
9 changes: 7 additions & 2 deletions minigalaxy/game.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,18 @@

class Game:
def __init__(self, name: str, url: str = "", md5sum=None, game_id: int = 0, install_dir: str = "",
image_url="", platform="linux", dlcs=None, category=""):
image_url="", platform=None, supported_platforms: list = None, dlcs=None, category=""):
self.name = name
self.url = url
self.md5sum = {} if md5sum is None else md5sum
self.id = game_id
self.install_dir = install_dir
self.image_url = image_url
self.platform = platform
self.dlcs = [] if dlcs is None else dlcs
self.category = category
self.status_file_path = self.get_status_file_path()
self.platform = platform if platform else self.get_info("platform")
self.supported_platforms = [platform] if supported_platforms is None else supported_platforms

def get_stripped_name(self):
return self.__strip_string(self.name)
Expand Down Expand Up @@ -144,6 +145,10 @@ def set_install_dir(self, install_dir) -> None:
if not self.install_dir:
self.install_dir = os.path.join(install_dir, self.get_install_directory_name())

def set_platform(self, platform):
self.platform = platform
self.set_info("platform", platform)

def __str__(self):
return self.name

Expand Down
2 changes: 1 addition & 1 deletion minigalaxy/installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ def make_tmp_dir(game):

def extract_installer(game: Game, installer: str, temp_dir: str, language: str, use_innoextract: bool):
# Extract the installer
if game.platform in ["linux"]:
if game.platform in ["linux"] and not game.get_info("platform") or game.get_info("platform") == "linux":
err_msg = extract_linux(installer, temp_dir)
else:
err_msg = extract_windows(game, installer, temp_dir, language, use_innoextract)
Expand Down
15 changes: 9 additions & 6 deletions minigalaxy/ui/gametile.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,9 +213,9 @@ def get_keep_executable_path(self):
break
return keep_path

def get_download_info(self, platform="linux"):
def get_download_info(self):
try:
download_info = self.api.get_download_info(self.game, platform)
download_info = self.api.get_download_info(self.game, self.api.get_download_version(self.game))
result = True
except NoDownloadLinkFound as e:
logger.error("No download link found", exc_info=1)
Expand Down Expand Up @@ -358,7 +358,7 @@ def __cancel(self, to_state):
def __download_update(self) -> None:
finish_func = self.__update
cancel_to_state = State.UPDATABLE
result, download_info = self.get_download_info(self.game.platform)
result, download_info = self.get_download_info()
if result:
result = self.__download(download_info, DownloadType.GAME_UPDATE, finish_func,
cancel_to_state)
Expand Down Expand Up @@ -387,15 +387,17 @@ def __update(self, save_location):
else:
self.image.set_tooltip_text(self.game.name)
for dlc in self.game.dlcs:
download_info = self.api.get_download_info(self.game, dlc_installers=dlc["downloads"]["installers"])
download_info = self.api.get_download_info(self.game, self.api.get_download_version(self.game),
dlc_installers=dlc["downloads"]["installers"])
if self.game.is_update_available(version_from_api=download_info["version"], dlc_title=dlc["title"]):
self.__download_dlc(dlc["downloads"]["installers"])

def __download_dlc(self, dlc_installers) -> None:
def finish_func(save_location):
self.__install_dlc(save_location, dlc_title=dlc_title)

download_info = self.api.get_download_info(self.game, dlc_installers=dlc_installers)
download_info = self.api.get_download_info(self.game, self.api.get_download_version(self.game),
dlc_installers=dlc_installers)
dlc_title = self.game.name
for dlc in self.game.dlcs:
if dlc["downloads"]["installers"] == dlc_installers:
Expand Down Expand Up @@ -442,7 +444,8 @@ def update_gtk_box_for_dlc(self, dlc_id, icon, title, installer):
self.dlc_horizontal_box.pack_start(dlc_box, False, True, 0)
dlc_box.show_all()
self.get_async_image_dlc_icon(dlc_id, image, icon, title)
download_info = self.api.get_download_info(self.game, dlc_installers=installer)
download_info = self.api.get_download_info(self.game, operating_system=self.api.get_download_version(self.game),
dlc_installers=installer)
if self.game.is_update_available(version_from_api=download_info["version"], dlc_title=title):
icon_name = "emblem-synchronizing"
self.dlc_dict[title][0].set_sensitive(True)
Expand Down
13 changes: 8 additions & 5 deletions minigalaxy/ui/gametilelist.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,9 +219,9 @@ def get_keep_executable_path(self):
break
return keep_path

def get_download_info(self, platform="linux"):
def get_download_info(self):
try:
download_info = self.api.get_download_info(self.game, platform)
download_info = self.api.get_download_info(self.game, self.api.get_download_version(self.game))
result = True
except NoDownloadLinkFound as e:
logger.error("No download link found", exc_info=1)
Expand Down Expand Up @@ -393,15 +393,17 @@ def __update(self, save_location):
else:
self.image.set_tooltip_text(self.game.name)
for dlc in self.game.dlcs:
download_info = self.api.get_download_info(self.game, dlc_installers=dlc["downloads"]["installers"])
download_info = self.api.get_download_info(self.game, self.api.get_download_version(self.game),
dlc_installers=dlc["downloads"]["installers"])
if self.game.is_update_available(version_from_api=download_info["version"], dlc_title=dlc["title"]):
self.__download_dlc(dlc["downloads"]["installers"])

def __download_dlc(self, dlc_installers) -> None:
def finish_func(save_location):
self.__install_dlc(save_location, dlc_title=dlc_title)

download_info = self.api.get_download_info(self.game, dlc_installers=dlc_installers)
download_info = self.api.get_download_info(self.game, self.api.get_download_version(self.game),
dlc_installers=dlc_installers)
dlc_title = self.game.name
for dlc in self.game.dlcs:
if dlc["downloads"]["installers"] == dlc_installers:
Expand Down Expand Up @@ -448,7 +450,8 @@ def update_gtk_box_for_dlc(self, dlc_id, icon, title, installer):
self.dlc_horizontal_box.pack_start(dlc_box, False, True, 0)
dlc_box.show_all()
self.get_async_image_dlc_icon(dlc_id, image, icon, title)
download_info = self.api.get_download_info(self.game, dlc_installers=installer)
download_info = self.api.get_download_info(self.game, operating_system=self.api.get_download_version(self.game),
dlc_installers=installer)
if self.game.is_update_available(version_from_api=download_info["version"], dlc_title=title):
icon_name = "emblem-synchronizing"
self.dlc_dict[title][0].set_sensitive(True)
Expand Down
17 changes: 16 additions & 1 deletion minigalaxy/ui/properties.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ class Properties(Gtk.Dialog):
button_properties_cancel = Gtk.Template.Child()
button_properties_ok = Gtk.Template.Child()
label_wine_custom = Gtk.Template.Child()
radiobutton_linux_type = Gtk.Template.Child()
radiobutton_windows_type = Gtk.Template.Child()
label_properties_platform = Gtk.Template.Child()

def __init__(self, parent, game, api):
Gtk.Dialog.__init__(self, title=_("Properties of {}").format(game.name), parent=parent.parent.parent,
Expand Down Expand Up @@ -93,6 +96,10 @@ def ok_pressed(self, button):
self.game.set_info("hide_game", self.switch_properties_hide_game.get_active())
self.game.set_info("custom_wine", str(self.button_properties_wine.get_filename()))
self.parent.parent.filter_library()
if self.radiobutton_linux_type.get_active():
self.game.set_platform("linux")
elif self.radiobutton_windows_type.get_active():
self.game.set_platform("windows")
self.destroy()

@Gtk.Template.Callback("on_button_properties_regedit_clicked")
Expand Down Expand Up @@ -134,10 +141,18 @@ def button_sensitive(self, game):
self.entry_properties_variable.set_sensitive(False)
self.entry_properties_command.set_sensitive(False)

if game.platform == 'linux':
if game.platform in ["linux"]:
self.button_properties_regedit.hide()
self.button_properties_winecfg.hide()
self.button_properties_winetricks.hide()
self.button_properties_wine.hide()
self.button_properties_reset.hide()
self.label_wine_custom.hide()
self.radiobutton_linux_type.set_active(True)
elif game.platform in ["windows"]:
self.radiobutton_windows_type.set_active(True)

if "linux" not in self.game.supported_platforms or game.is_installed():
self.radiobutton_linux_type.hide()
self.radiobutton_windows_type.hide()
self.label_properties_platform.hide()
Loading