Humble Bundle support
[GameHub.git] / src / data / sources / humble / HumbleGame.vala
blob7cd065c8f1588b909f01297433af43cb0f9551fe
1 using Gtk;
2 using Gee;
3 using GameHub.Utils;
5 namespace GameHub.Data.Sources.Humble
7 public class HumbleGame: Game
9 private bool _is_for_linux;
11 private string order_id;
12 public File executable { get; private set; }
14 private string installation_dir_name
16 owned get
18 return name.escape().replace(" ", "_").replace(":", "");
22 public HumbleGame(Humble src, string order, Json.Object json)
24 source = src;
25 id = json.get_string_member("machine_name");
26 name = json.get_string_member("human_name");
27 image = json.get_string_member("icon");
28 icon = image;
29 order_id = order;
31 _is_for_linux = false;
33 foreach(var dl in json.get_array_member("downloads").get_elements())
35 if(dl.get_object().get_string_member("platform") == "linux")
37 _is_for_linux = true;
38 break;
42 if(!_is_for_linux)
44 GamesDB.get_instance().add_unsupported_game(source, id);
45 return;
48 executable = FSUtils.file(FSUtils.Paths.Humble.Games, installation_dir_name + "/start.sh");
50 custom_info = @"{\"order\":\"$(order_id)\",\"executable\":\"$(executable.get_path())\"}";
53 public HumbleGame.from_db(Humble src, Sqlite.Statement stmt)
55 source = src;
56 id = stmt.column_text(1);
57 name = stmt.column_text(2);
58 icon = stmt.column_text(3);
59 image = stmt.column_text(4);
60 custom_info = stmt.column_text(5);
61 _is_for_linux = true;
63 var custom_json = Parser.parse_json(custom_info).get_object();
64 order_id = custom_json.get_string_member("order");
65 executable = FSUtils.file(custom_json.get_string_member("executable"));
68 public override async bool is_for_linux()
70 return _is_for_linux;
73 public override bool is_installed()
75 return executable.query_exists();
78 public override async void install(DownloadProgress progress = (d, t) => {})
80 var token = ((Humble) source).user_token;
82 var headers = new HashMap<string, string>();
83 headers["Cookie"] = @"$(Humble.AUTH_COOKIE)=\"$(token)\";";
85 var root = (yield Parser.parse_remote_json_file_async(@"https://www.humblebundle.com/api/v1/order/$(order_id)?ajax=true", "GET", null, headers)).get_object();
86 var products = root.get_array_member("subproducts");
88 if(products == null) return;
90 var installers = new ArrayList<Game.Installer>();
92 foreach(var product_node in products.get_elements())
94 var product = product_node.get_object();
95 if(product.get_string_member("machine_name") != id) continue;
97 foreach(var dl_node in product.get_array_member("downloads").get_elements())
99 var dl = dl_node.get_object();
100 var id = dl.get_string_member("machine_name");
101 var os = dl.get_string_member("platform");
102 if(os != "linux") continue;
104 foreach(var dls_node in dl.get_array_member("download_struct").get_elements())
106 var installer = new Installer(id, os, dls_node.get_object());
107 installers.add(installer);
112 if(installers.size < 1) return;
114 var wnd = new GameHub.UI.Dialogs.GameInstallDialog(this, installers);
116 wnd.canceled.connect(() => Idle.add(install.callback));
118 wnd.install.connect(installer => {
119 var link = installer.file;
120 var local = FSUtils.expand(FSUtils.Paths.Humble.Installers, "humble_" + installer.id);
122 FSUtils.mkdir(FSUtils.Paths.Humble.Games);
123 FSUtils.mkdir(FSUtils.Paths.Humble.Installers);
125 Downloader.get_instance().download.begin(File.new_for_uri(link), { local }, progress, null, (obj, res) => {
128 var file = Downloader.get_instance().download.end(res);
129 var path = file.get_path();
130 var install_dir = FSUtils.expand(FSUtils.Paths.Humble.Games, installation_dir_name);
131 FSUtils.mkdir(install_dir);
132 Utils.run(@"chmod +x \"$(path)\"");
134 var info = file.query_info(FileAttribute.STANDARD_CONTENT_TYPE, FileQueryInfoFlags.NONE);
135 var type = info.get_content_type();
137 var cmd = @"/usr/bin/env xdg-open $(path)"; // unknown type, just open
139 switch(type)
141 case "application/x-executable":
142 case "application/x-elf":
143 case "application/x-sh":
144 case "application/x-shellscript":
145 cmd = @"$(path) -- --i-agree-to-all-licenses --noreadme --nooptions --noprompt --destination $(install_dir)"; // probably mojosetup
146 break;
148 case "application/zip":
149 case "application/x-tar":
150 case "application/x-gtar":
151 case "application/x-cpio":
152 case "application/x-bzip2":
153 case "application/gzip":
154 case "application/x-lzip":
155 case "application/x-lzma":
156 case "application/x-7z-compressed":
157 case "application/x-rar-compressed":
158 cmd = @"/usr/bin/env file-roller $(path) -e $(install_dir)"; // extract with file-roller
159 break;
162 Utils.run_async.begin(cmd, (obj, res) => {
163 Utils.run_async.end(res);
164 Utils.run(@"chmod -R +x \"$(install_dir)\"");
166 var chooser = new FileChooserDialog(_("Select main executable of the game"), GameHub.UI.Windows.MainWindow.instance,
167 FileChooserAction.OPEN, _("Cancel"), ResponseType.CANCEL, _("Select"), ResponseType.ACCEPT);
168 var filter = new FileFilter();
169 filter.add_mime_type("application/x-executable");
170 filter.add_mime_type("application/x-elf");
171 filter.add_mime_type("application/x-sh");
172 filter.add_mime_type("text/x-shellscript");
173 chooser.set_filter(filter);
174 chooser.select_file(executable);
176 if(chooser.run() == ResponseType.ACCEPT)
178 executable = chooser.get_file();
179 custom_info = @"{\"order\":\"$(order_id)\",\"executable\":\"$(executable.get_path())\"}";
180 GamesDB.get_instance().add_game(this);
183 chooser.destroy();
185 Idle.add(install.callback);
188 catch(Error e)
190 warning(e.message);
195 wnd.show_all();
196 wnd.present();
198 yield;
201 public override async void run()
203 if(is_installed())
205 var path = executable.get_path();
206 yield Utils.run_async(@"$(path)");
210 public class Installer: Game.Installer
212 public string dl_name;
214 public override string name { get { return dl_name; } }
216 public Installer(string machine_name, string platform, Json.Object download)
218 id = machine_name;
219 os = platform;
220 dl_name = download.get_string_member("name");
221 file = download.get_object_member("url").get_string_member("web");