Last active
January 6, 2021 00:45
-
-
Save jefvel/6a152077bd8f441d093e130f796c9166 to your computer and use it in GitHub Desktop.
HashLink + Heaps game launcher with auto updating using bintray
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package; | |
import hxd.Event; | |
import sys.io.Process; | |
import haxe.io.BytesInput; | |
import format.zip.Reader; | |
import haxe.Http; | |
import haxe.Json; | |
import sys.FileSystem; | |
import sys.io.File; | |
import hxd.Window; | |
import sys.thread.Thread; | |
import hxd.res.DefaultFont; | |
import h2d.Text; | |
typedef ManifestData = { | |
?gameVersion:String, | |
} | |
typedef BintrayVersion = { | |
name:String, | |
} | |
typedef ThreadMsg = { | |
type:String, | |
data:Dynamic, | |
} | |
class Main extends hxd.App { | |
// Your bintray username | |
static final bintrayUser = "jefvel"; | |
// The bintray repo to look in | |
static final bintrayRepo = "karanten"; | |
// The bintray package to look for | |
// Versions should contain one file, | |
// which is a zip containing the compiled game data file | |
static final bintrayPackage = "data"; | |
// set this to either "hl", or "./hl" or "./yourgame" or whatever you named the hashlink executable | |
static final hashlinkExecutable = "hl"; | |
// The local game file will be called this | |
static final gameFile = "game.dat"; | |
// Local manifest info file | |
static final manifestFile = "manifest.json"; | |
var bintrayAPI = 'https://api.bintray.com/packages/$bintrayUser/$bintrayRepo'; | |
var bintrayDLURL = 'https://dl.bintray.com/$bintrayUser/$bintrayRepo'; | |
var text:Text; | |
var localManifest:ManifestData; | |
var gameReady = false; | |
var mainThread:Thread; | |
public override function init() { | |
hl.UI.closeConsole(); | |
text = new Text(DefaultFont.get(), s2d); | |
text.textColor = 0xFFFFFF; | |
mainThread = Thread.current(); | |
loadLocalManifest(); | |
downloadFun(); | |
Window.getInstance().addEventTarget(onEvent); | |
} | |
function onEvent(e:Event) { | |
if (e.kind == EPush) { | |
launchGame(); | |
} | |
} | |
function loadLocalManifest() { | |
localManifest = {}; | |
if (FileSystem.exists(manifestFile)) { | |
var mstring = File.getContent(manifestFile); | |
try { | |
localManifest = Json.parse(mstring); | |
} catch (e) {} | |
} | |
if (localManifest.gameVersion != null) { | |
log('Local version is ${localManifest.gameVersion}'); | |
} else { | |
log("No local version detected"); | |
} | |
} | |
override function update(dt:Float) { | |
super.update(dt); | |
var msg:ThreadMsg = Thread.readMessage(false); | |
if (msg != null) { | |
if (msg.type == "log") { | |
log(msg.data); | |
} | |
if (msg.type == "newManifest") { | |
var m:ManifestData = msg.data; | |
File.saveContent(manifestFile, Json.stringify(m)); | |
} | |
if (msg.type == "gameReady") { | |
gameReady = true; | |
log("Click to start"); | |
} | |
} | |
} | |
function log(msg) { | |
text.text += '$msg\n'; | |
} | |
function sendGameReady() { | |
mainThread.sendMessage({ | |
type: "gameReady", | |
}); | |
} | |
function downloadFun() { | |
log("Getting latest version..."); | |
Thread.create(() -> { | |
function log(msg) { | |
mainThread.sendMessage({ | |
type: "log", | |
data: msg, | |
}); | |
} | |
var latestVersion = ""; | |
// Fetch latest version info from bintray | |
var http = new haxe.Http('$bintrayAPI/$bintrayPackage/versions/_latest'); | |
http.onData = function(data:String) { | |
var result:BintrayVersion = haxe.Json.parse(data); | |
latestVersion = result.name; | |
} | |
http.request(); | |
if (latestVersion != localManifest.gameVersion) { | |
log("Downloading latest version..."); | |
} else { | |
log("Game is up to date"); | |
sendGameReady(); | |
return; | |
} | |
// Fetch file path for latest version from bintray | |
http = new Http('$bintrayAPI/$bintrayPackage/versions/$latestVersion/files'); | |
var filePath = ""; | |
http.onData = data -> { | |
var blob = Json.parse(data); | |
var f = blob[0]; | |
filePath = f.path; | |
} | |
http.request(); | |
// Download latest binary | |
http = new Http('$bintrayDLURL/$filePath'); | |
var redirectURL = ""; | |
http.onStatus = s -> { | |
if (s == 302) { | |
redirectURL = http.responseHeaders.get("Location"); | |
} | |
} | |
http.request(); | |
http = new Http(redirectURL); | |
http.request(); | |
log("Downloaded binary. Uncompressing..."); | |
File.saveBytes(filePath, http.responseBytes); | |
var fi = sys.io.File.read(filePath); | |
var r = new haxe.zip.Reader(fi); | |
var f = r.read(); | |
for (handle in f) { | |
var r = new haxe.zip.Reader(new BytesInput(handle.data)); | |
trace(handle.compressed); | |
var bytes = Reader.unzip(handle); | |
File.saveBytes(gameFile, bytes); | |
} | |
fi.close(); | |
FileSystem.deleteFile(filePath); | |
log("Uncompressed latest version"); | |
var m:ManifestData = { | |
gameVersion: latestVersion, | |
} | |
mainThread.sendMessage({ | |
type: "newManifest", | |
data: m, | |
}); | |
sendGameReady(); | |
}); | |
} | |
function launchGame() { | |
if (!gameReady) { | |
return; | |
} | |
new Process(hashlinkExecutable, [gameFile, '--savedir=${Sys.getCwd()}'], true); | |
Sys.exit(0); | |
} | |
static function main() { | |
new Main(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment