commit 133613add811e3452c9ff5baa5a6c58bd7be6982 Author: Paul Liverman III Date: Sun Mar 25 09:46:03 2018 -0700 init version from Asteroid Dodge diff --git a/ReadMe.md b/ReadMe.md new file mode 100644 index 0000000..67da3df --- /dev/null +++ b/ReadMe.md @@ -0,0 +1,50 @@ +# itchy + +A super simple version checker for use with [LÖVE](https://love2d.org) games +published on [itch.io](https://itch.io/). + +## Installation + +Just copy `check.lua` to where you want in your source. + +## Usage + +Start it in its own thread, and send a table on the "send-itchy" channel with +information on what you're looking for. + +```lua +-- initialize +versionCheck = love.thread.newThread("lib/itchy/check.lua") +versionCheckSend = thread.getChannel("send-itchy") +versionCheck:start() +versionCheckSend:push({ + target = "guard13007/asteroid-dodge" + -- other options are available!! +}) +-- receive info +versionCheckReceive = thread.getChannel("receive-itchy") +if versionCheckReceive:getCount() > 0 then + -- this could be a version or an error message! + latest_version = versionCheckReceive:demand() +end +``` + +### Options + +* `url` (string) If you have a different URL to check for the latest version + from, you can specify it here. +* `target` REQUIRED (string) The target string of your game on itch.io + (username/game-slug) +* `channel` (string) If you do not specify the channel name to look for on + itch.io, it will use `osx` for Mac OS / OS X, `win32` for Windows, `linux` for + Linux, `android` for Android, `ios` for iOS, and if any other OS is returned + by `love.system.getOS()` it will use that string as-is. +* `version` (any) Version of the game running right now. +* `proxy` (string) This library uses an [HTTP proxy](https://github.com/Guard13007/insecure-proxy) + for the HTTPS call to itch.io's API. By default it uses `https://104.236.139.220:16343` + which is a DigitalOcean VPS I own. If you'd rather use a different proxy + server, you can specify it here. +* `interval` (number) If specified, a check for the latest version will happen + again every `interval` seconds. +* `send_interval_errors` DEFAULT false (boolean) Whether or not checks happening + on an interval will report errors. diff --git a/check.lua b/check.lua new file mode 100644 index 0000000..006cac3 --- /dev/null +++ b/check.lua @@ -0,0 +1,77 @@ +require("love.timer") +local thread, timer +do + local _obj_0 = love + thread, timer = _obj_0.thread, _obj_0.timer +end +local http = require("socket.http") +local receive = thread.getChannel("send-itchy") +local send = thread.getChannel("receive-itchy") +local check +check = function(data, send_errors) + if send_errors == nil then + send_errors = true + end + local exponential_backoff = 1 + while true do + local body, status + if data.url then + body, status = http.request(data.url) + elseif data.proxy then + body, status = http.request(tostring(data.proxy) .. "/get/https://itch.io/api/1/x/wharf/latest?target=" .. tostring(data.target) .. "&channel_name=" .. tostring(data.channel)) + end + if status == 200 then + local latest = body:match('%s*{%s*"latest"%s*:%s*"(.+)"%s*}%s*') + send:push(latest) + return true + else + if send_errors then + send:push("unknown, error getting latest version: HTTP " .. tostring(status) .. ", trying again in " .. tostring(exponential_backoff) .. " seconds") + end + timer.sleep(exponential_backoff) + exponential_backoff = exponential_backoff * 2 + end + end +end +local start +start = function() + local data = receive:demand() + if not (data.target) then + error("Target undefined. Cannot search for latest version of unknown target!") + end + if not (data.version) then + data.version = "0" + end + if not (data.proxy or data.url) then + data.proxy = "http://104.236.139.220:16343" + end + if not (data.channel) then + require("love.system") + local os = love.system.getOS() + local _exp_0 = os + if "OS X" == _exp_0 then + data.channel = "osx" + elseif "Windows" == _exp_0 then + data.channel = "win32" + elseif "Linux" == _exp_0 then + data.channel = "linux" + elseif "Android" == _exp_0 then + data.channel = "android" + elseif "iOS" == _exp_0 then + data.channel = "ios" + else + data.channel = os + end + end + check(data) + if data.interval then + while true do + timer.sleep(data.interval) + if receive:getCount() > 0 then + return start() + end + check(data, data.send_interval_errors) + end + end +end +return start() diff --git a/check.moon b/check.moon new file mode 100644 index 0000000..3f0f1a1 --- /dev/null +++ b/check.moon @@ -0,0 +1,67 @@ +require "love.timer" +import thread, timer from love + +http = require "socket.http" +receive = thread.getChannel "send-itchy" +send = thread.getChannel "receive-itchy" + +check = (data, send_errors=true) -> + exponential_backoff = 1 + while true + local body, status + if data.url + body, status = http.request data.url + elseif data.proxy + body, status = http.request "#{data.proxy}/get/https://itch.io/api/1/x/wharf/latest?target=#{data.target}&channel_name=#{data.channel}" + + if status == 200 + latest = body\match '%s*{%s*"latest"%s*:%s*"(.+)"%s*}%s*' + send\push latest + return true + else + if send_errors + send\push "unknown, error getting latest version: HTTP #{status}, trying again in #{exponential_backoff} seconds" + timer.sleep exponential_backoff + exponential_backoff = exponential_backoff * 2 + +start = -> + -- data should be a table of information + data = receive\demand! + unless data.target + error "Target undefined. Cannot search for latest version of unknown target!" + + data.version = "0" unless data.version + data.proxy = "http://104.236.139.220:16343" unless data.proxy or data.url + + -- channel can be autodetected if not specified + unless data.channel + require "love.system" + os = love.system.getOS! + switch os + when "OS X" + data.channel = "osx" + when "Windows" + data.channel = "win32" + when "Linux" + data.channel = "linux" + when "Android" + data.channel = "android" + when "iOS" + data.channel = "ios" + else + data.channel = os + + check data + + -- if we should check again every x seconds, wait, and do so + if data.interval + while true + timer.sleep data.interval + + -- if we are sent new data, start over entirely + if receive\getCount! > 0 + return start! + + check data, data.send_interval_errors + +start!