Skip to content

Commit

Permalink
Restrict NSIS installers unpacking with file-roller
Browse files Browse the repository at this point in the history
Support adding custom games using installers (tkashkin#106)
Implement custom emulators removal
  • Loading branch information
tkashkin committed Nov 1, 2018
1 parent 75a5015 commit 7e443e4
Show file tree
Hide file tree
Showing 8 changed files with 207 additions and 42 deletions.
2 changes: 1 addition & 1 deletion src/data/Game.vala
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ namespace GameHub.Data

var type = yield guess_type(file, f > 0);

if(type == InstallerType.WINDOWS_EXECUTABLE)
if(type == InstallerType.WINDOWS_EXECUTABLE && tool is Compat.Innoextract)
{
var desc = yield Utils.run_thread({"file", "-b", path});
if(desc != null && desc.length > 0 && NSIS_INSTALLER_DESCRIPTION in desc)
Expand Down
15 changes: 13 additions & 2 deletions src/data/compat/Wine.vala
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ namespace GameHub.Data.Compat
public string arch { get; construct; default = "win64"; }
public File? wine_binary { get; protected set; }

public CompatTool.BoolOption install_opt_innosetup_args;

public Wine(string binary="wine", string arch="win64")
{
Object(binary: binary, arch: arch);
Expand All @@ -42,7 +44,10 @@ namespace GameHub.Data.Compat
executable = wine_binary = Utils.find_executable(binary);
installed = executable != null && executable.query_exists();

install_opt_innosetup_args = new CompatTool.BoolOption("InnoSetup", _("InnoSetup default options"), true);

install_options = {
install_opt_innosetup_args,
new CompatTool.BoolOption("/SILENT", _("Silent installation"), false),
new CompatTool.BoolOption("/VERYSILENT", _("Very silent installation"), true),
new CompatTool.BoolOption("/SUPPRESSMSGBOXES", _("Suppress messages"), true),
Expand Down Expand Up @@ -81,11 +86,17 @@ namespace GameHub.Data.Compat
protected virtual async string[] prepare_installer_args(Game game)
{
var win_path = yield convert_path(game, game.install_dir);
string[] opts = { "/SP-", "/NOCANCEL", "/NOGUI", "/NOICONS", @"/DIR=$(win_path)", "/LOG=C:\\install.log" };

string[] opts = {};

if(install_opt_innosetup_args.enabled)
{
opts = { "/SP-", "/NOCANCEL", "/NOGUI", "/NOICONS", @"/DIR=$(win_path)", "/LOG=C:\\install.log" };
}

foreach(var opt in install_options)
{
if(opt is CompatTool.BoolOption && ((CompatTool.BoolOption) opt).enabled)
if(opt.name.has_prefix("/") && opt is CompatTool.BoolOption && ((CompatTool.BoolOption) opt).enabled)
{
opts += opt.name;
}
Expand Down
70 changes: 65 additions & 5 deletions src/data/sources/user/UserGame.vala
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,37 @@ namespace GameHub.Data.Sources.User
private bool is_removed = false;
public signal void removed();

public UserGame(string name, File dir, File exec, string args)
private Installer? installer;

public UserGame(string name, File dir, File exec, string args, bool is_installer)
{
source = User.instance;

this.id = Utils.md5(name + Random.next_int().to_string());
this.name = name;

platforms.clear();
platforms.add(Platform.LINUX);
platforms.add(exec.get_path().has_suffix(".exe") ? Platform.WINDOWS : Platform.LINUX);

install_dir = dir;
executable = exec;

arguments = args;

if(!is_installer)
{
executable = exec;
}
else
{
installer = new Installer(this, exec);
var root_object = new Json.Object();
root_object.set_string_member("installer", exec.get_path());
var root_node = new Json.Node(Json.NodeType.OBJECT);
root_node.set_object(root_object);
info = Json.to_string(root_node, false);
save();
}

((User) source).add_game(this);
update_status();
}
Expand Down Expand Up @@ -95,10 +112,39 @@ namespace GameHub.Data.Sources.User
public override async void update_game_info()
{
update_status();
if(installer == null && info != null && info.length > 0)
{
var i = Parser.parse_json(info).get_object();
installer = new Installer(this, File.new_for_path(i.get_string_member("installer")));
}
save();
}

public override async void install(){}
public override async void install()
{
yield update_game_info();

if(installer == null) return;

var installers = new ArrayList<Game.Installer>();
installers.add(installer);

var wnd = new GameHub.UI.Dialogs.GameInstallDialog(this, installers);

wnd.cancelled.connect(() => Idle.add(install.callback));

wnd.install.connect((installer, dl_only, tool) => {
installer.install.begin(this, dl_only, tool, (obj, res) => {
installer.install.end(res);
Idle.add(install.callback);
});
});

wnd.show_all();
wnd.present();

yield;
}

public override async void uninstall()
{
Expand All @@ -122,7 +168,7 @@ namespace GameHub.Data.Sources.User

public override void update_status()
{
var state = executable.query_exists() ? Game.State.INSTALLED : Game.State.UNINSTALLED;
var state = executable != null && executable.query_exists() ? Game.State.INSTALLED : Game.State.UNINSTALLED;
status = new Game.Status(state);
if(state == Game.State.INSTALLED)
{
Expand All @@ -135,5 +181,19 @@ namespace GameHub.Data.Sources.User
remove_tag(Tables.Tags.BUILTIN_INSTALLED);
}
}

public class Installer: Game.Installer
{
private string game_name;
public override string name { get { return game_name; } }

public Installer(UserGame game, File installer)
{
game_name = game.name;
id = "installer";
platform = installer.get_path().has_suffix(".exe") ? Platform.WINDOWS : Platform.LINUX;
parts.add(new Game.Installer.Part("installer", installer.get_uri(), full_size, installer, installer));
}
}
}
}
15 changes: 7 additions & 8 deletions src/ui/dialogs/CompatRunDialog.vala
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,6 @@ namespace GameHub.UI.Dialogs

content = new Box(Orientation.VERTICAL, 0);

var icon = new AutoSizeImage();
icon.set_constraint(48, 48, 1);
icon.set_size_request(48, 48);

title_label = new Label(game.name);
title_label.margin_start = 8;
title_label.halign = Align.START;
Expand All @@ -79,11 +75,17 @@ namespace GameHub.UI.Dialogs

content.add(opts_list);

if(game is Game)
if(game is Game && (game as Game).icon != null)
{
var icon = new AutoSizeImage();
icon.set_constraint(48, 48, 1);
icon.set_size_request(48, 48);
Utils.load_image.begin(icon, (game as Game).icon, "icon");
hbox.add(icon);
}

hbox.add(content);

response.connect((source, response_id) => {
switch(response_id)
{
Expand All @@ -98,9 +100,6 @@ namespace GameHub.UI.Dialogs
run_btn.get_style_context().add_class(Gtk.STYLE_CLASS_SUGGESTED_ACTION);
run_btn.grab_default();

hbox.add(icon);
hbox.add(content);

get_content_area().add(hbox);
get_content_area().set_size_request(340, 96);

Expand Down
35 changes: 25 additions & 10 deletions src/ui/dialogs/GameInstallDialog.vala
Original file line number Diff line number Diff line change
Expand Up @@ -62,29 +62,34 @@ namespace GameHub.UI.Dialogs

content = new Box(Orientation.VERTICAL, 0);

var icon = new AutoSizeImage();
icon.set_constraint(48, 48, 1);
icon.set_size_request(48, 48);

title_label = new Label(null);
title_label.margin_start = title_label.margin_end = 8;
title_label.margin_start = title_label.margin_end = 4;
title_label.halign = Align.START;
title_label.hexpand = true;
title_label.get_style_context().add_class(Granite.STYLE_CLASS_H2_LABEL);

subtitle_label = new Label(null);
subtitle_label.margin_start = subtitle_label.margin_end = 8;
subtitle_label.margin_start = subtitle_label.margin_end = 4;
subtitle_label.halign = Align.START;
subtitle_label.hexpand = true;

hbox.add(icon);
if(game.icon != null)
{
var icon = new AutoSizeImage();
icon.set_constraint(48, 48, 1);
icon.set_size_request(48, 48);
Utils.load_image.begin(icon, game.icon, "icon");
hbox.add(icon);
title_label.margin_start = title_label.margin_end = 8;
subtitle_label.margin_start = subtitle_label.margin_end = 8;
}

hbox.add(content);

content.add(title_label);
content.add(subtitle_label);

title_label.label = game.name;
Utils.load_image.begin(icon, game.icon, "icon");

installers_list = new ListBox();
installers_list.margin_top = 4;
Expand Down Expand Up @@ -147,7 +152,7 @@ namespace GameHub.UI.Dialogs
var compat_tool_box = new Box(Orientation.VERTICAL, 4);

compat_tool_picker = new CompatToolPicker(game, true);
compat_tool_picker.margin_start = 4;
compat_tool_picker.margin_start = game.icon != null ? 4 : 0;
compat_tool_picker.margin_top = 8;

compat_tool_box.add(compat_tool_picker);
Expand Down Expand Up @@ -180,7 +185,7 @@ namespace GameHub.UI.Dialogs
compat_tool_box.add(opts_list);
}

add_button(_("Import"), GameInstallDialog.RESPONSE_IMPORT);
var import_btn = add_button(_("Import"), GameInstallDialog.RESPONSE_IMPORT);

var install_btn = add_button(_("Install"), ResponseType.ACCEPT);
install_btn.get_style_context().add_class(STYLE_CLASS_SUGGESTED_ACTION);
Expand All @@ -199,6 +204,16 @@ namespace GameHub.UI.Dialogs
bbox.set_child_non_homogeneous(dl_only_check, true);
}

if(game is GameHub.Data.Sources.User.UserGame)
{
subtitle_label.no_show_all = true;
subtitle_label.visible = false;
dl_only_check.no_show_all = true;
dl_only_check.visible = false;
import_btn.no_show_all = true;
import_btn.visible = false;
}

if(compat_tool_revealer != null)
{
dl_only_check.toggled.connect(() => {
Expand Down
35 changes: 32 additions & 3 deletions src/ui/dialogs/SettingsDialog/tabs/Emulators.vala
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ namespace GameHub.UI.Dialogs.SettingsDialog.Tabs
public class Emulators: SettingsDialogTab
{
private Stack stack;
private Button add_btn;
private Button remove_btn;

private EmulatorPage? previous_page;

public Emulators(SettingsDialog dlg)
Expand Down Expand Up @@ -62,10 +65,10 @@ namespace GameHub.UI.Dialogs.SettingsDialog.Tabs
actionbar.vexpand = false;
actionbar.get_style_context().add_class(Gtk.STYLE_CLASS_INLINE_TOOLBAR);

var add_btn = new Button.from_icon_name("list-add-symbolic", IconSize.MENU);
add_btn = new Button.from_icon_name("list-add-symbolic", IconSize.MENU);
add_btn.get_style_context().add_class(Gtk.STYLE_CLASS_FLAT);

var remove_btn = new Button.from_icon_name("list-remove-symbolic", IconSize.MENU);
remove_btn = new Button.from_icon_name("list-remove-symbolic", IconSize.MENU);
remove_btn.get_style_context().add_class(Gtk.STYLE_CLASS_FLAT);

actionbar.pack_start(add_btn);
Expand Down Expand Up @@ -98,6 +101,10 @@ namespace GameHub.UI.Dialogs.SettingsDialog.Tabs
add_emu_page();
});

remove_btn.clicked.connect(() => {
remove_emu_page();
});

var emulators = Tables.Emulators.get_all();
foreach(var emu in emulators)
{
Expand All @@ -115,6 +122,20 @@ namespace GameHub.UI.Dialogs.SettingsDialog.Tabs
{
stack.set_visible_child(page);
}
page.emulator.removed.connect(() => {
stack.remove(page);
remove_btn.sensitive = stack.get_children().length() > 0;
});
remove_btn.sensitive = stack.get_children().length() > 0;
}

private void remove_emu_page()
{
var page = stack.visible_child as EmulatorPage;
if(page != null)
{
page.remove();
}
}

private class EmulatorPage: Box
Expand All @@ -129,7 +150,10 @@ namespace GameHub.UI.Dialogs.SettingsDialog.Tabs
set
{
_title = value.strip();
stack.child_set(this, title: _title);
if(parent == stack)
{
stack.child_set(this, title: _title);
}
}
}
public Stack stack { get; construct; }
Expand Down Expand Up @@ -242,6 +266,11 @@ namespace GameHub.UI.Dialogs.SettingsDialog.Tabs
emulator.save();
}

public new void remove()
{
emulator.remove();
}

private Box add_switch(string text, bool enabled, owned SettingsDialogTab.SwitchAction action)
{
var sw = new Switch();
Expand Down
Loading

0 comments on commit 7e443e4

Please sign in to comment.