From e18cae33f98d019dce78092f9fed9b9646509697 Mon Sep 17 00:00:00 2001 From: Jonathan Morrison <87885521+jonjongames1997@users.noreply.github.com> Date: Mon, 27 Apr 2026 09:35:54 -0400 Subject: [PATCH 1/2] Handle empty HTTP response in versionCheck Return early in the PerformHttpRequest callback when the response body is nil or not a string to avoid runtime errors when iterating with string.gmatch. Adds a debug log including the error info and prevents further processing of an empty/invalid remote response. --- modules/versionCheck/server/versionCheck.lua | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/versionCheck/server/versionCheck.lua b/modules/versionCheck/server/versionCheck.lua index c728fbb..ddfc98b 100644 --- a/modules/versionCheck/server/versionCheck.lua +++ b/modules/versionCheck/server/versionCheck.lua @@ -11,6 +11,11 @@ function ps.versionCheck(script, link, updateLink) end PerformHttpRequest(link, function(err, text, headers) + if not text or type(text) ~= "string" then + ps.debug("Empty or invalid HTTP response for version check: " .. tostring(err)) + return + end + local remoteVersion = nil local changelogLines = {} for line in string.gmatch(text, "[^\r\n]+") do From e0cbd06886bfd4843ccc0278fa9902638cb3757f Mon Sep 17 00:00:00 2001 From: Jonathan Morrison <87885521+jonjongames1997@users.noreply.github.com> Date: Mon, 27 Apr 2026 11:58:01 -0400 Subject: [PATCH 2/2] Enhance versionCheck with parsing & comparison Add robust version parsing and comparison utilities (ps._splitVersion, ps._compareVersions) and refactor ps.versionCheck to validate inputs, fetch and parse remote version tokens (handles "Newest Build:" and semantic version patterns), compare installed vs remote versions, and log appropriate messages. Supports an opts.showChangelog flag to optionally display changelog lines and includes a convenience example call. Improved error handling and clearer debug/warn/info output. --- modules/versionCheck/server/versionCheck.lua | 86 +++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) diff --git a/modules/versionCheck/server/versionCheck.lua b/modules/versionCheck/server/versionCheck.lua index ddfc98b..0293c83 100644 --- a/modules/versionCheck/server/versionCheck.lua +++ b/modules/versionCheck/server/versionCheck.lua @@ -45,6 +45,90 @@ function ps.versionCheck(script, link, updateLink) end, "GET", "", "") end -- TODO: on release ill need to PR this to get the raw link for version check :) -ps.versionCheck('ps_lib', 'https://raw.githubusercontent.com/Project-Sloth/ps_lib/refs/heads/main/changelog.txt', 'https://github.com/Project-Sloth/ps_lib') +function ps._splitVersion(v) + local parts = {} + for num in string.gmatch(v or "", "(%d+)") do + table.insert(parts, tonumber(num)) + end + return parts +end + +function ps._compareVersions(a, b) + local pa = ps._splitVersion(a) + local pb = ps._splitVersion(b) + local n = math.max(#pa, #pb) + for i = 1, n do + local va = pa[i] or 0 + local vb = pb[i] or 0 + if va < vb then + return -1 + elseif va > vb then + return 1 + end + end + return 0 +end + +function ps.versionCheck(script, link, updateLink, opts) + opts = opts or {} + if not script or not link then + ps.debug("versionCheck: invalid parameters") + return + end + + local currentVersion = GetResourceMetadata(script, "version", 0) + if not currentVersion or currentVersion == "" then + ps.debug("versionCheck: could not retrieve current version for " .. tostring(script)) + return + end + + PerformHttpRequest(link, function(statusOrErr, body, headers) + if not body or type(body) ~= "string" then + ps.debug("versionCheck: empty or invalid HTTP response: " .. tostring(statusOrErr)) + return + end + + local remoteVersion + local changelogLines = {} + + -- Try to extract a line like: Newest Build: 1.2.3 or a semantic version token + for line in string.gmatch(body, "[^\r\n]+") do + if not remoteVersion then + local m = string.match(line, "Newest Build:%s*(%S+)") or string.match(line, "version[:%s]+(%S+)") + if m then + remoteVersion = m + else + local sem = string.match(line, "(%d+%.%d+%.%d+[-%+%w]*)") + if sem then + remoteVersion = sem + end + end + else + table.insert(changelogLines, line) + end + end + + if not remoteVersion then + ps.debug("versionCheck: remote version not found in response") + return + end + + local cmp = ps._compareVersions(currentVersion, remoteVersion) + if cmp == 0 then + ps.success('^2 ' .. tostring(script) .. ' is up to date: ' .. tostring(currentVersion)) + elseif cmp < 0 then + ps.warn('^1 ' .. tostring(script) .. ' is outdated! Installed: ' .. tostring(currentVersion) .. ' Available: ' .. tostring(remoteVersion)) + ps.warn('Download: ' .. (updateLink or 'not provided')) + if opts.showChangelog and #changelogLines > 0 then + ps.info('Changelog:\n' .. table.concat(changelogLines, '\n')) + end + else + ps.info('^3 ' .. tostring(script) .. ' has a newer version installed (' .. tostring(currentVersion) .. ') than remote (' .. tostring(remoteVersion) .. ').') + end + end, "GET", "", { }) +end + +-- Example convenience call +ps.versionCheck('ps_lib', 'https://raw.githubusercontent.com/Project-Sloth/ps_lib/refs/heads/main/changelog.txt', 'https://github.com/Project-Sloth/ps_lib', { showChangelog = false }) exports('versionCheck', ps.versionCheck) \ No newline at end of file