| … | … | @@ -1,17 +1,35 @@ |
| 1 | 1 | extends Node |
| 2 | 2 | |
| 3 | const URLParser = preload('../utils/URLParser.gd') |
| 4 | |
| 3 | 5 | class_name HyperGateway |
| 4 | 6 | |
| 5 | 7 | signal starting_gateway() |
| 6 | 8 | signal started_gateway(pid) |
| 7 | 9 | |
| 8 | | export var processPID = 0 |
| 9 | | export var serverPrefix = "http://127.0.0.1:4973/hyper/" |
| 10 | | export var storageDirectory = 'user://gateway-data/' |
| 11 | | export var autoStart = false |
| 10 | signal started_download(version) |
| 11 | signal finished_download(version) |
| 12 | |
| 12 | 13 | export var writable = true |
| 13 | 14 | export var persist = true |
| 14 | 15 | |
| 16 | export var autoStart = true |
| 17 | export var autoDownload = true |
| 18 | export var autoUpdate = false |
| 19 | |
| 20 | export var storageDirectory = "user://gateway-data/" |
| 21 | export var repositoryName = "rangermauve/hyper-gateway" |
| 22 | export var tagStart = "v2" |
| 23 | |
| 24 | ## TODO: Use this tag if the `latest` release doesn't match the tag? |
| 25 | # export var defaultTag = "v2.1.3" |
| 26 | |
| 27 | var processPID = 0 |
| 28 | var latestInfoRequest = HTTPRequest.new() |
| 29 | var downloadFileRequest = HTTPRequest.new() |
| 30 | var downloadingVersion = null |
| 31 | var downloadThread = null |
| 32 | |
| 15 | 33 | func _notification(what): |
| 16 | 34 | if what == MainLoop.NOTIFICATION_WM_QUIT_REQUEST: |
| 17 | 35 | cleanupGateway() |
| … | … | @@ -19,8 +37,21 @@ func _notification(what): |
| 19 | 37 | |
| 20 | 38 | # Called when the node enters the scene tree for the first time. |
| 21 | 39 | func _ready(): |
| 22 | | if autoStart: ensureSetup() |
| 23 | | pass # Replace with function body. |
| 40 | ensureStorageLocation() |
| 41 | add_child(latestInfoRequest) |
| 42 | latestInfoRequest.connect("request_completed", self, "_on_got_latest") |
| 43 | |
| 44 | add_child(downloadFileRequest) |
| 45 | downloadFileRequest.connect("request_completed", self, "_on_finished_download") |
| 46 | |
| 47 | if autoStart: |
| 48 | start() |
| 49 | |
| 50 | func start(): |
| 51 | autoStart = true |
| 52 | if autoDownload: |
| 53 | ensureDownloaded() |
| 54 | else: ensureSetup() |
| 24 | 55 | |
| 25 | 56 | func cleanupGateway(): |
| 26 | 57 | if processPID == 0: |
| … | … | @@ -28,30 +59,22 @@ func cleanupGateway(): |
| 28 | 59 | return |
| 29 | 60 | print('Cleaning up gateway ' + str(processPID)) |
| 30 | 61 | OS.kill(processPID) |
| 31 | | pass |
| 32 | | |
| 33 | | func _resolvePath(path): |
| 34 | | var file = File.new() |
| 35 | | file.open(path, File.READ) |
| 36 | | var finalPath = file.get_path_absolute() |
| 37 | | file.close() |
| 38 | | return finalPath |
| 39 | 62 | |
| 40 | 63 | func setupGateway(): |
| 41 | 64 | emit_signal("starting_gateway") |
| 42 | 65 | var executiblePath = getExecutiblePath() |
| 43 | | var path = _resolvePath(executiblePath) |
| 66 | var path = ProjectSettings.globalize_path(executiblePath) |
| 44 | 67 | |
| 45 | 68 | var args = ["run"] |
| 46 | 69 | if !persist: args.append('--no-persist') |
| 47 | 70 | if writable: args.append('--writable') |
| 48 | 71 | |
| 49 | | var resolvedStorageDirectory = _resolvePath(storageDirectory) |
| 72 | var resolvedStorageDirectory = ProjectSettings.globalize_path(storageDirectory) |
| 50 | 73 | args.append('--storage-location') |
| 51 | 74 | args.append(resolvedStorageDirectory) |
| 52 | | |
| 53 | | print("Starting gateway from " + path) |
| 54 | | |
| 75 | |
| 76 | print("Starting gateway from ",path, " with args ", args) |
| 77 | |
| 55 | 78 | # Start the hyper-gateway in a process |
| 56 | 79 | processPID = OS.execute(path, args, false) |
| 57 | 80 | |
| … | … | @@ -61,23 +84,116 @@ func setupGateway(): |
| 61 | 84 | |
| 62 | 85 | print("Started gateway at " + str(processPID)) |
| 63 | 86 | emit_signal("started_gateway", processPID) |
| 64 | | pass |
| 65 | 87 | |
| 66 | 88 | func ensureSetup(): |
| 67 | | if processPID != 0: return |
| 89 | if processPID != 0: return |
| 68 | 90 | setupGateway() |
| 69 | | pass |
| 70 | | |
| 71 | | func getExecutiblePath(): |
| 91 | |
| 92 | func getExecutibleName(): |
| 72 | 93 | var name = OS.get_name() |
| 73 | | if name == 'X11': return "res://hyper-gateway/hyper-gateway-linux" |
| 74 | | if name == 'OSX': return "res://hyper-gateway/hyper-gateway-macos" |
| 75 | | if name == 'Windows': return "res://hyper-gateway/hyper-gateway-windows.exe" |
| 94 | if name == 'X11': return "hyper-gateway-linux" |
| 95 | if name == 'OSX': return "hyper-gateway-macos" |
| 96 | if name == 'Windows': return "hyper-gateway-windows.exe" |
| 76 | 97 | push_error("Can not start gateway, invalid operating system " + name) |
| 77 | | pass |
| 78 | 98 | |
| 79 | | func defaultDirectory(): |
| 99 | func getCurrentVersion(): |
| 100 | var file = File.new() |
| 101 | var err = file.open(getVersionFilePath(), File.READ) |
| 102 | if err != OK: |
| 103 | printerr('No existing binary version found', err) |
| 104 | return "" |
| 105 | var version = file.get_as_text() |
| 106 | file.close() |
| 107 | return version |
| 108 | |
| 109 | func saveCurrentVersion(version): |
| 110 | var file = File.new() |
| 111 | file.open(getVersionFilePath(), File.WRITE) |
| 112 | file.store_string(version) |
| 113 | file.close() |
| 114 | |
| 115 | func getVersionFilePath(): |
| 116 | return storageDirectory + 'version.txt' |
| 117 | |
| 118 | func getExecutiblePath(): |
| 119 | var executibleName = getExecutibleName() |
| 120 | return storageDirectory + executibleName |
| 121 | |
| 122 | func ensureStorageLocation(): |
| 80 | 123 | var dir = Directory.new() |
| 81 | | dir.open('user://gateway-data/') |
| 82 | | return dir.get_current_dir() |
| 83 | | pass |
| 124 | var err = dir.make_dir_recursive(storageDirectory) |
| 125 | if err != OK: |
| 126 | printerr("Unable to create storage directory ", err) |
| 127 | |
| 128 | func hasBinary(): |
| 129 | var version = getCurrentVersion() |
| 130 | return version && version.length() |
| 131 | |
| 132 | func ensureDownloaded(): |
| 133 | if autoUpdate || !hasBinary(): |
| 134 | checkLatestVersion() |
| 135 | elif autoStart: |
| 136 | ensureSetup() |
| 137 | |
| 138 | func checkLatestVersion(): |
| 139 | var url = latestURL() |
| 140 | print('Getting latest version from ' + url) |
| 141 | latestInfoRequest.request(url, [], true, HTTPClient.METHOD_GET) |
| 142 | |
| 143 | func _on_got_latest(_result, response_code, _headers, body): |
| 144 | print('Latest info response', response_code) |
| 145 | var parsed = JSON.parse(body.get_string_from_utf8()) |
| 146 | if parsed.error != OK: |
| 147 | printerr("Unable to parse latest version from GitHub:", parsed.error_string) |
| 148 | return |
| 149 | var info = parsed.result |
| 150 | var newVersion = info.tag_name |
| 151 | |
| 152 | print('Latest version:', newVersion) |
| 153 | |
| 154 | var existing = getCurrentVersion() |
| 155 | |
| 156 | if newVersion != existing: downloadLatest(info.assets, newVersion) |
| 157 | elif autoStart: ensureSetup() |
| 158 | |
| 159 | func downloadLatest(assets, version): |
| 160 | var toDownload = null |
| 161 | var executibleName = getExecutibleName() |
| 162 | for asset in assets: |
| 163 | if asset.name != executibleName: continue |
| 164 | toDownload = asset |
| 165 | if !toDownload: |
| 166 | printerr("Unable to find valid executible in latest release") |
| 167 | return |
| 168 | |
| 169 | var fromURL = toDownload.browser_download_url |
| 170 | var toPath = getExecutiblePath() |
| 171 | |
| 172 | print('Downloading latest binary:',fromURL) |
| 173 | |
| 174 | downloadFileRequest.set_download_file(toPath) |
| 175 | |
| 176 | downloadingVersion = version |
| 177 | emit_signal("started_download", version) |
| 178 | |
| 179 | downloadFileRequest.request(fromURL, [], true,HTTPClient.METHOD_GET) |
| 180 | |
| 181 | func _on_finished_download(_result, response_code, _headers, _body): |
| 182 | var executiblePath = getExecutiblePath() |
| 183 | var path = ProjectSettings.globalize_path(executiblePath) |
| 184 | var os = OS.get_name() |
| 185 | |
| 186 | # Mark file as executible if not on Windows |
| 187 | if os != "Windows": |
| 188 | OS.execute("chmod", ["+x", path]) |
| 189 | |
| 190 | print("Finished download ", response_code) |
| 191 | saveCurrentVersion(downloadingVersion) |
| 192 | emit_signal("finished_download", downloadingVersion) |
| 193 | if autoStart: ensureSetup() |
| 194 | |
| 195 | func repoURL(): |
| 196 | return "https://api.github.com/repos/" + repositoryName + "/" |
| 197 | |
| 198 | func latestURL(): |
| 199 | return repoURL() + "releases/latest" |