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
18 return name
.escape().replace(" ", "_").replace(":", "");
22 public HumbleGame(Humble src
, string order
, Json
.Object json
)
25 id
= json
.get_string_member("machine_name");
26 name
= json
.get_string_member("human_name");
27 image
= json
.get_string_member("icon");
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")
44 GamesDB
.get_instance().add_unsupported_game(source
, id
);
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
)
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);
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()
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
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
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
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
);
185 Idle
.add(install
.callback);
201 public override async
void run()
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
)
220 dl_name
= download
.get_string_member("name");
221 file
= download
.get_object_member("url").get_string_member("web");